<template>
  <div id="jx-modify-virtual-machine" class="jx-virtual-machine" v-loading="deskLoading" :element-loading-text="deskLoadingText" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
    <div class="jx-virtual-machine-header">
      <div class="jx-virtual-machine-header-name">{{courseName}}</div>
      <div class="jx-virtual-machine-header-name">/&nbsp;{{taskName}}</div>
      <!-- <div class="jx-virtual-machine-nav" v-show="!fullScreen">
				<span class="fl active">实验手册</span>
			</div> -->
      <div class="jx-virtual-machine-header-info fr">
        <i class="iconfont icon-jingshi"></i>
        <el-tooltip effect="light" placement="top">
          <div slot="content" v-if="VirtualMachineInfo.length>0">
            模板类型：<span v-if="VirtualMachineInfo.length == 1">单节点</span>
            <span v-else-if="VirtualMachineInfo.length >= 2">集群</span>
            <div style="line-height:20px;" v-for="(item, index) in VirtualMachineInfo" :key="index">
              {{ item.containerRole }}
              <br />
              ip：{{ item.ip }}
              <br />
              配置：{{ item.flavor }}
              <br />
              镜像名称：{{ item.imageName }}
              <div style="line-height:20px;" v-for="(subItem, subIndex) in item.ports" :key="subIndex">
                端口名称：{{ subItem.portName }}
                <br />
                容器内地址：{{ subItem.port }}
                <br />
                访问地址：{{ `${subItem.ip}:${subItem.exposedPort}` }}
              </div>
            </div>
          </div>
          <div slot="content" v-else>
            暂无虚拟机信息
          </div>
          <span>虚拟机信息</span>

        </el-tooltip>
      </div>
      <!-- <div class="jx-virtual-machine-header-dropout fr">
                <i class="iconfont icon-Group-" @click="DropoutVirtual"></i>
            </div> -->
      <div class="jx-virtual-machine-nav2 fr" v-show="VirtualMachineUrlArr.length > 1">
        <span class="fl" :class="{ active : MachineNavTabIndex == index}" v-for="(item, index) in VirtualMachineUrlArr" @click="MachineNavTab2(index, item)" :key="index">{{ item.containerRole }}</span>
      </div>
    </div>
    <div class="jx-virtual-machine-main">
      <!-- 左侧非全屏导航-->
      <div class="step-main-content fl" v-show="!fullScreen">
        <div class="task-nav">
          <p>
            <el-button :style="navIndex==1?'background-color: #1277eb;color: #fff;':''" type="primary" plain size="mini" @click="MachineNavTab(1)">竞赛题目</el-button>
            <el-button :style="navIndex==2?'background-color: #1277eb;color: #fff;':''" type="primary" plain size="mini" @click="MachineNavTab(2)">判定设置</el-button>
            <el-button :style="navIndex==3?'background-color: #1277eb;color: #fff;':''" type="primary" plain size="mini" @click="MachineNavTab(3)">参考答案</el-button>
          </p>
        </div>
        <!-- 竞赛题目 -->
        <div v-show="navIndex===1">
          <div>
            <div class="jx-main-content">
              <div class="step-main-content-box">
                <mavonEditor class="step-main-editor" ref="question"></mavonEditor>
              </div>
              <div class="step-main-btn-group">
                <button class="button-style" @click="noteSubmit(1,1)">保存</button>
              </div>
            </div>
          </div>
        </div>
        <!-- 判定设置 -->
        <div v-show="navIndex===2">
          <div class="task-judge">
            <el-button v-show="!add_on_off" class="adds" type="primary" round size="mini" @click="addJudge()">添加判定</el-button>
            <div v-show="add_on_off" class="save-btn" style="margin-right:20px ;">
              <el-button type="warning" size="mini" @click="cancelJudge()" round>取消</el-button>
              <el-button type="primary" size="mini" @click="saveJudge()" round>保存</el-button>
            </div>
            <!-- 判定条件添加 -->
            <div v-show="add_on_off" class="judge">
              <!-- 添加或者修改的不同判断规则名称 -->
              <div class="judge-title">判定规则{{add_or_amend?this.judgeList.length+1:this.nameNumber}}</div>
              <!-- 表单 -->
              <form class="judge-info" ref="form" :model="form">
                <!-- <div class="save-btn">
                  <el-button type="warning" size="mini" @click="cancelJudge()" round>取消</el-button>
                  <el-button type="primary" size="mini" @click="saveJudge()" round>保存</el-button>
                </div> -->
                <!-- 判定得分 -->
                <div class="form-item info-one">
                  <span class="item-label"> 判定得分: </span>
                  <el-input v-model="form.score" style="width:150px;margin-right:10px" @input="checkScore()"></el-input>
                  <span style="color:#F56C6C">{{warning}}</span>
                </div>
                <!-- 判定题目 -->
                <div class="form-item info-two">
                  <span class="item-label"> 判定题目: </span>
                  <el-input type="textarea" maxlength="20000" show-word-limit v-model="form.examQuestion" rows="5" resize="none"></el-input>
                </div>
                <!-- 判定输出结果 -->
                <div class="form-item info-two">
                  <span slot="label" class="item-label"> 判定输出结果 </span>
                  <el-radio-group v-model="judgeType">
                    <el-radio :label="1">环境安装/进程检查</el-radio>
                    <el-radio :label="2">单数值</el-radio>
                    <el-radio :label="3">字符串/数组/集合</el-radio>
                    <el-radio :label="4">命令/SQL命令</el-radio>
                  </el-radio-group>

                  <el-input type="textarea" maxlength="20000" show-word-limit v-model="form.answer" rows="9" resize="none"></el-input>
                  <!-- 校验规则 -->
                  <div>
                    <div class="name">校验规则</div>
                    <!-- 一 -->
                    <div v-show="this.judgeType == 1">
                      <el-radio-group v-model="form.answerRuleType">
                        <el-radio :label="1">内容一致（不要求顺序）</el-radio>
                        <el-radio :label="2">输出结果包含判定结果</el-radio>
                      </el-radio-group>
                    </div>
                    <!-- 二 -->
                    <div v-show="this.judgeType == 2">
                      <el-radio-group v-model="form.answerRuleType">
                        <el-radio :label="1">完全一致</el-radio>
                        <el-radio :label="2">数值趋近</el-radio>
                      </el-radio-group>

                      <div class="more-info" v-show="form.answerRuleType == 2 &&this.judgeType==2">
                        <span>允许前误差
                          <el-input v-model="form.numberParam[0].numberParamErrorValueBefore" @keyup.native="inputJudge1($event)" @input="inputJudge2($event,0,'numberParamErrorValueBefore')" oninput="if(value>999)value=999;if(value<0)value=0"></el-input>
                        </span>
                        <span>允许后误差
                          <el-input v-model="form.numberParam[0].numberParamErrorValueAfter" @keyup.native="inputJudge1($event)" @input="inputJudge2($event,0,'numberParamErrorValueAfter')" oninput="if(value>999)value=999;if(value<0)value=0"></el-input>
                        </span>
                      </div>
                    </div>
                    <!-- 三 -->
                    <div v-show="this.judgeType == 3">
                      <el-radio-group v-model="form.answerRuleType">
                        <el-radio :label="1">完全一致</el-radio>
                        <el-radio :label="2">内容一致（不要求顺序）</el-radio>
                        <el-radio :label="3">数值趋近<div class="addErrorCondition" @click.stop="addErrorCondition()">增加</div>
                        </el-radio>
                      </el-radio-group>

                      <div class="more-info" v-show="form.answerRuleType == 3 &&this.judgeType==3" ref="errorCondition">
                        <div class="more-info-item" v-for="(item,index) in form.numberParam" :key="index">
                          <span>{{index+1}}.</span>
                          <span>第
                            <el-input v-model="item.rowNum" oninput="value=(''+value).replace(/[^\d]+/g, '');if(value>999)value=999;if(value<0)value=0"></el-input>行
                            <el-input v-model="item.columnNum" oninput="value=(''+value).replace(/[^\d]+/g, '');if(value>999)value=999;if(value<0)value=0"></el-input>列
                          </span>
                          <span>数值允许前误差
                            <el-input v-model="item.numberParamErrorValueBefore" @keyup.native="inputJudge1($event)" @input="inputJudge2($event,index,'numberParamErrorValueBefore')" oninput="if(value>999)value=999;if(value<0)value=0"></el-input>
                          </span>
                          <span>允许后误差
                            <el-input v-model="item.numberParamErrorValueAfter" @keyup.native="inputJudge1($event)" @input="inputJudge2($event,index,'numberParamErrorValueAfter')" oninput="if(value>999)value=999;if(value<0)value=0"></el-input>
                          </span>
                          <div v-show="form.numberParam.length==index+1&&form.numberParam.length>1" class="canceErrorCondition" @click.stop="canceErrorCondition(item)">
                            <div class="cance-line"></div>
                          </div>
                        </div>
                      </div>
                    </div>
                    <!-- 四 -->
                    <div v-show="this.judgeType == 4">
                      <el-radio-group v-model="form.answerRuleType">
                        <el-radio :label="1">内容包含（不要求顺序）</el-radio>
                      </el-radio-group>
                    </div>
                  </div>
                </div>
                <!-- 校验过程 -->
                <div class="form-item info-three">
                  <span slot="label" class="item-label"> 校验过程 </span>
                  <el-radio-group v-model="form.scriptType">
                    <el-radio :label="1">代码执行脚本</el-radio>
                    <el-radio :label="2">结果比对路径</el-radio>
                    <el-radio :label="3">执行命令</el-radio>
                  </el-radio-group>
                  <el-input type="textarea" maxlength="1000" show-word-limit v-model="form.script" rows="9" resize="none"></el-input>
                </div>
              </form>
            </div>
            <!-- 判定列表渲染 -->
            <div v-show="!add_on_off && judgeList.length>0">
              <div class="judge" v-for="(items,index) in judgeList" :key="index">
                <div class="judge-title">判定规则{{index+1}}</div>
                <form class="judge-info" ref="form" :model="items">
                  <div class="save-btn">
                    <el-button type="danger" size="mini" @click="deleteJudge(items.id)" round>删除</el-button>
                    <el-button type="primary" size="mini" @click="amendJudge(items,index)" round>修改</el-button>
                  </div>

                  <div class="form-item info-one">
                    <span class="item-label"> 判定得分: </span>
                    <el-input :value="items.score" style="width:150px;margin-right:10px" readonly></el-input>
                    <!-- <span>各判定规则之和不得超过任务分数</span> -->
                  </div>
                <!-- 判定题目 -->
                <div class="form-item info-two">
                <span class="item-label"> 判定题目: </span>
                <el-input type="textarea" v-model="items.examQuestion" rows="5" resize="none" readonly></el-input>
                </div>
                  <div class="form-item info-two" label="判定输出结果">
                    <span slot="label" class="item-label"> 判定输出结果 </span>
                    <el-radio-group :value="items.judgeType" readonly>
                      <el-radio :label="1">环境安装/进程检查</el-radio>
                      <el-radio :label="2">单数值</el-radio>
                      <el-radio :label="3">字符串/数组/集合</el-radio>
                      <el-radio :label="4">命令/SQL命令</el-radio>
                    </el-radio-group>

                    <el-input type="textarea" :value="items.answer" rows="9" resize="none" readonly></el-input>
                    <!-- 校验规则 -->
                    <div>
                      <div class="name">校验规则</div>
                      <!-- 1 -->
                      <div v-show="items.judgeType == 1">
                        <el-radio-group :value="items.answerRuleType" readonly>
                          <el-radio :label="1">内容一致（不要求顺序）</el-radio>
                          <el-radio :label="2">输出结果包含判定结果</el-radio>
                        </el-radio-group>
                      </div>
                      <!-- 2 -->
                      <div v-show="items.judgeType == 2">
                        <el-radio-group :value="items.answerRuleType" readonly>
                          <el-radio :label="1">完全一致</el-radio>
                          <el-radio :label="2">数值趋近</el-radio>
                        </el-radio-group>
                        <!-- items.numberParam!=undefined  -->
                        <div class="more-info" v-if="items.answerRuleType == 2 && items.judgeType==2">
                          <span>允许前误差
                            <input :value="items.numberParam[0].numberParamErrorValueBefore" class="inputs" readonly />
                          </span>
                          <span>允许后误差
                            <input :value="items.numberParam[0].numberParamErrorValueAfter" class="inputs" readonly />
                          </span>
                        </div>
                      </div>
                      <!-- 3 -->
                      <div v-show="items.judgeType == 3">
                        <el-radio-group :value="items.answerRuleType" readonly>
                          <el-radio :label="1">完全一致</el-radio>
                          <el-radio :label="2">内容一致（不要求顺序）</el-radio>
                          <el-radio :label="3">数值趋近<div class="addErrorCondition" @click.stop="addErrorCondition()">增加</div>
                          </el-radio>
                        </el-radio-group>
                        <div class="more-info" v-if="items.answerRuleType == 3 &&items.judgeType==3">
                          <div class="more-info-item" v-for="(item,index) in items.numberParam" :key="index">
                            <span>{{index+1}}.</span>
                            <span>第
                              <input :value="item.rowNum" type="text" class="inputs" readonly />行
                              <input :value="item.columnNum" type="text" class="inputs" readonly />列</span>
                            <span>数值允许前误差
                              <input :value="item.numberParamErrorValueBefore" class="inputs" readonly />
                            </span>
                            <span>允许后误差
                              <input :value="item.numberParamErrorValueAfter" class="inputs" readonly />
                            </span>
                          </div>
                        </div>
                      </div>
                      <!-- 四 -->
                      <div v-show="items.judgeType == 4">
                        <el-radio-group v-model="form.answerRuleType">
                          <el-radio :label="1">内容包含（不要求顺序）</el-radio>
                        </el-radio-group>
                      </div>
                    </div>
                  </div>

                  <div class="form-item info-three" label="代码执行脚本">
                    <span slot="label" class="item-label"> 校验过程 </span>
                    <el-radio-group :value="items.scriptType" readonly>
                      <el-radio :label="1">代码执行脚本</el-radio>
                      <el-radio :label="2">结果比对路径</el-radio>
                      <el-radio :label="3">执行命令</el-radio>
                    </el-radio-group>
                    <el-input type="textarea" :value="items.script" rows="9" resize="none" readonly></el-input>
                  </div>
                </form>
              </div>
            </div>
            <!-- 暂无数据 -->
            <div class="no-judge" v-if="!add_on_off &&judgeList.length==0">
              <div class="no-data-tips">
                <img src="./../../../assets/images/index_no_data.png" />
                <p>暂无内容</p>
              </div>
            </div>
          </div>
        </div>
        <!-- 参考答案 -->
        <div v-show="navIndex===3">
          <div>
            <div class="jx-main-content">
              <div class="step-main-content-box">
                <mavonEditor class="step-main-editor" ref="referenceAnswer"></mavonEditor>
              </div>
              <div class="step-main-btn-group">
                <button class="button-style" @click="noteSubmit(1,2)">保存</button>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!--右侧导航-->
      <div class="step-main-mirror fl">
        <div class="mirror-iframe" v-if="!mirrorIframeTip">
          <template v-for="(item, index) in VirtualMachineUrlArr">
            <iframe name="iframeitem" :key="index" :id="'VirtualMachineIframe' + item.containerId" v-if="item.notebook" v-show="MachineNavTabIndex == index" :src="item.notebookUrl" width="100%" :height="iframeHeight" frameborder="0" class="iframs"></iframe>
            <iframe name="iframeitem" :key="index" :id="'VirtualMachineIframe' + item.containerId" v-else v-show="MachineNavTabIndex == index" :src="item.desktopUrl" width="100%" :height="iframeHeight" frameborder="0" class="iframs"></iframe>
          </template>
          <!-- <iframe name="iframeitem" v-for="(item, index) in VirtualMachineUrlArr" :id="'VirtualMachineIframe' + item.containerId"  v-show="MachineNavTabIndex == index" :src="item.desktopUrl" width="100%" :height="iframeHeight" frameborder="0" class="iframs"></iframe> -->
        </div>
        <div class="mirror-iframe-tip" v-if="mirrorIframeTip">
          <img src="./../../../assets/images/mirror_iframe_tip.png" />
          <span class="mirror-iframe-tip-text">{{ mirrorIframeTipText }}</span>
          <el-button class="button-style" @click="refreshVirtual(0)">刷 新</el-button>
        </div>
        <!-- 全屏左侧导航 -->
        <div class="fullSide" v-if="fullScreen">
          <ul>
            <li @click="HandbookDialog(1)">
              <i class="iconfont icon-shiyongshouce"></i>
              <p>题目</p>
            </li>
          </ul>
          <ul>
            <li @click="HandbookDialog(2)">
              <i class="iconfont icon-shiyongshouce"></i>
              <p>答案</p>
            </li>
          </ul>
        </div>
        <!-- 全屏右侧导航 -->
        <div class="step-main-mirror-dialog" :style="{ right: mirrorRightWidth + 'px'}" v-show="VirtualMachineUrl">
          <div class="step-main-mirror-dialog-block">
            <div class="step-main-mirror-dialog-box">
              <div class="quit-machine" @click="DropoutVirtual">
                <img src="@/assets/images/close.png" alt="" srcset="">
                关闭实验
              </div>
              <div class="mirror-dialog-header">
                <!-- 计时 -->
                <Time :autoStart="true"></Time>
              </div>
              <div class="mirror-dialog-item">
                <div class="item-btn">
                  <span @click="refreshVirtual(0)">
                    <i class="iconfont icon-shuaxin"></i>刷新
                  </span>
                </div>
                <div class="item-btn">
                  <span @click="InitVirtual">
                    <i class="iconfont icon-zhongxinshiyang"></i>初始化
                  </span>
                  <el-tooltip class="item" effect="light" content="初始化实验环境" placement="left-end">
                    <i class="iconfont icon-wenti-m"></i>
                  </el-tooltip>
                </div>
                <div class="item-btn" v-if="!fullScreen">
                  <span @click="VirtualFullScreen(2)">
                    <i class="iconfont icon-full-screen"></i>虚拟机全屏
                  </span>
                </div>
                <div class="item-btn" v-if="fullScreen">
                  <span @click="VirtualFullScreen(3)">
                    <i class="iconfont icon-full-screen"></i>退出全屏
                  </span>
                </div>
                <div class="item-btn">
                  <span @click="VirtualSave">
                    <i class="iconfont icon-baocun1"></i>镜像保存
                  </span>
                </div>
                <div class="item-btn">
                  <span @click="VirtualLink">
                    <i class="iconfont icon-peizhiguanli"></i>重选配置
                  </span>
                </div>
              </div>
              <div class="mirror-dialog-item">
                <div class="item-btn">
                  <span @click="SftpConfig">
                    <i class="iconfont icon-upload"></i>SFTP工具
                  </span>
                </div>
                <div class="item-btn">
                  <span @click="UploadFile">
                    <i class="iconfont icon-shangchuan-"></i>文件上传
                  </span>
                  <!-- <el-tooltip class="item" effect="light" content="上传文件至虚拟机/root/tools/文件夹" placement="left-end" style="position:absolute; right: -10px; top: 5px;">
                                        <i class="iconfont icon-wenti-m"></i>
                                    </el-tooltip> -->
                </div>
              </div>
              <div class="mirror-dialog-item" v-if="VirtualMachineUrlArr[0] && !VirtualMachineUrlArr[0].notebook">
                <!-- <div class="item-btn">
                  <span @click="ExperimentScreenshot">
                    <i class="iconfont icon-jietu1"></i>实验截图
                  </span>
                </div> -->
                <div class="item-btn">
                  <span @click="CutDialog">
                    <i class="iconfont icon-jietu"></i>剪切板
                  </span>
                </div>
              </div>
            </div>
          </div>
          <div class="step-main-mirror-arrow" @click="MirrorArrowFn" v-if="VirtualMachineUrl">
            <div>工具栏</div>
          </div>
        </div>
      </div>
    </div>
    <!-- 实验截图 -->
    <el-dialog :close-on-click-modal="false" class="dialog-screenshot" title="实验截图" :visible.sync="dialogScreenshot" width="800px">
      <div class="dialog-content clear-fix">
        <img :src="dialogScreenshotUrl" />
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button class="button-style" @click="dialogScreenshotCopy" :data-clipboard-text="'<img src='+dialogScreenshotCopyUrl+'>'">复 制</el-button>
        <el-button class="button-style" @click="dialogScreenshotSave">保 存</el-button>
      </span>
    </el-dialog>
    <!-- 学生实验手册显示隐藏 -->
    <el-dialog :close-on-click-modal="false" class="dialog-handbook" title="学生实验手册显示隐藏" :visible.sync="dialogHandbook" width="460px">
      <div class="dialog-content clear-fix">
        <p>控制该章节学生端所有实验手册显隐</p>
        <p>当前学生端实验手册为 <span>显示</span>
        </p>
        <div class="handbook-item">
          <span class="item-label">设置：</span>
          <el-radio-group>
            <el-radio label="显示"></el-radio>
            <el-radio label="隐藏"></el-radio>
          </el-radio-group>
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button class="button-style" @click="dialogHandbook = false">取 消</el-button>
        <el-button class="button-style" @click="dialogHandbook = false">确 定</el-button>
      </span>
    </el-dialog>
    <!-- 竞赛题目弹窗 -->
    <el-dialog class="dialog-hand-book" v-dialogDragResize title="竞赛题目" style="height:525px" :modal="false" :close-on-click-modal="false" :visible.sync="dialogHandbookDrag1" :modal-append-to-body="false">
      <div style="height:100%;">
        <div class="dialog-body">
          <mavonEditor style="height:100%;" ref="TheProblem"></mavonEditor>
        </div>
        <div slot="footer" class="dialog-footer" style="text-align:center;margin-top:20px">
          <el-button class="button-style" @click="noteSubmit(2,1)">确 定</el-button>
        </div>
      </div>
    </el-dialog>
    <!-- 参考答案弹窗 -->
    <el-dialog class="dialog-hand-book" v-dialogDragResize title="参考答案" style="height:525px" :modal="false" :close-on-click-modal="false" :visible.sync="dialogHandbookDrag2" :modal-append-to-body="false">
      <div style="height:100%;">
        <div class="dialog-body">
          <mavonEditor style="height:100%;" ref="TheAnswer"></mavonEditor>
        </div>
        <div slot="footer" class="dialog-footer" style="text-align:center;margin-top:20px">
          <el-button class="button-style" @click="noteSubmit(2,2)">确 定</el-button>
        </div>
      </div>
    </el-dialog>
    <!-- SFTP -->
    <el-dialog :close-on-click-modal="false" class="sftp-dialog" title="SFTP工具" :visible.sync="dialogSftp" width="540px">
      <div class="sftp-content">
        <div class="sftp-header">
          <div class="sftp-title">
            您可以使用SFTP工具上传、下载文件:
          </div>
          <p>SFTP访问的地址为 <span>{{ sftpPort[0] }}</span> 端口号为 :
            <span>{{ sftpPort[1] }}</span>
          </p>
          <p>用户名 : <span>root </span> 密码 : <span>root</span>
          </p>
        </div>
        <div class="sftp-desc">
          <div class="sftp-title">
            上传工具为WinSCP
          </div>
          <div class="desc-item">
            <p>
              <img class="item-pic" src="./../../../assets/images/sftp.png" />
              <a :href="sftpIp[1]+'/WinSCP_64-Setup.exe'">
                <i class="iconfont icon-tubiaozhizuo-">
                  <!-- <img src="./../../../assets/images/sftp_icon1.png" /> -->
                </i>
                立即下載
              </a>
              <!-- <a :href="sftpIp[1]+'/WinSCP_64-Setup.exe'">
                                <i class="iconfont icon-xiazai2">
                                    <img src="./../../../assets/images/sftp_icon2.png" />
                                </i>
                            </a> -->
            </p>
          </div>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button class="button-style" @click="dialogSftp = false">确定</el-button>
      </div>
    </el-dialog>
    <!-- 剪切板 -->
    <el-dialog :close-on-click-modal="false" class="cut-dialog" title="剪切板" :visible.sync="dialogCut" width="655px" @close="CutCloseDialog">
      <div class="cut-title">
        <p>
          <span>复制外部内容到实验环境内 : </span>粘贴内容到下方输入框一点击保存
        </p>
      </div>
      <el-form :model="cutData.cutRuleForm" :rules="cutData.cutRules" ref="cutRuleForm">
        <el-form-item prop="desc">
          <el-input type="textarea" @input="CutContentInput" maxlength="20000" v-model="cutData.cutRuleForm.desc" style="height:200px;"></el-input>
          <div class="desc-num">{{cutData.cutRuleForm.descNum}}/20000</div>
        </el-form-item>
        <el-form-item style="text-align:center;">
          <el-button class="button-style" @click="cutSubmitForm('cutRuleForm')">保存</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
    <!-- 文件上传 -->
    <el-dialog :close-on-click-modal="false" class="common-tool-dialog" title="文件上传" :visible.sync="dialogFileUpload" width="460px" @close="CloseFileUploadDialog">
      <el-form :model="FileUploadForm" :rules="FileUploadRules" ref="FileUploadForm">
        <el-form-item class="version-file">
          <el-button class="button-style">上传文件
            <input id="version-file-upload" type="file" multiple="multiple" auto-complete="off" @change="getFile">
            </input>
          </el-button>
          <p style="float:left; line-height: 36px; color: #1277eb; margin-left: 5px;">
            上传文件至虚拟机/root/tools/文件夹</p>
          <p style="float:left; margin-top: 20px; word-break:break-all; width: 100%;" v-if="FileUploadForm.versionFile.length>0">已选: {{FileUploadForm.versionFile}}</p>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer" style="text-align:center;">
        <el-button class="button-style" style="width: 100px;" @click="UploadSave('FileUploadForm')">上传至虚机</el-button>
      </div>
    </el-dialog>
    <!-- 关闭分享 -->
    <el-dialog :close-on-click-modal="false" class="dialog-download-file" title="关闭分享" :visible.sync="dialogCloseShare" width="460px">
      <div class="dialog-content">
        <p>是否关闭分享</p>
      </div>
      <span slot="footer" class="dialog-footer">
        <!-- <el-button class="button-style" @click="CloseShare">关 闭</el-button> -->
        <el-button class="button-style" @click="dialogCloseShare = false">取 消</el-button>
      </span>
    </el-dialog>
    <!-- 保存镜像 -->
    <el-dialog :close-on-click-modal="false" class="dialog-mirror-save" title="保存镜像信息" :visible.sync="dialogMirrorInfo" v-if='dialogMirrorInfo' width="820px">
      <el-form label-width="100px" :rules="MirrorFormRules" :model="MirrorForm" ref='MirrorForm'>
        <el-form-item label="保存方式：" v-if="saveWayStatus">
          <el-radio-group v-model="MirrorForm.saveWay" @change="MirrorRadioChange">
            <el-radio :label="1">覆盖原镜像</el-radio>
            <el-radio :label="2">新生成镜像</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="镜像名称：" prop="MirrorName">
          <el-input type="text" v-model="MirrorForm.MirrorName" maxlength="50" @input="MirrorNameInput"></el-input>
          <p style="position:absolute; left:240px; top: 10px; color:#bbb;">
            {{MirrorForm.MirrorNameNum}}/50</p>
          <span style="position:absolute; left:300px; top: 2px; color:#bbb;" v-if="gpuStatus">GPU镜像</span>
          <span style="position:absolute; left:300px; top: 2px; color:#bbb;" v-if="notebookStatus">NoteBook镜像</span>
        </el-form-item>
        <div style="width: 100%; float:left;">
          <span class="label" style="margin:6px 0 0px 8px">
            <span style="color:#F56C6C">*</span> 镜像图标：
          </span>
          <div class="distribution-swpier">
            <swiper :options="swiperDialogOption">
              <swiper-slide v-for="(item, index) in iconListData" :key="index">
                <div class="distribution-box" @click="IconChange(item.icon)">
                  <img :src="item.iconUrl" />
                  <i class="iconfont icon-zhengque" v-if="item.icon == MirrorForm.iconId"></i>
                </div>
              </swiper-slide>
            </swiper>
            <div class="swiper-btn swiper-button-prev" slot="button-prev" v-show="iconListData.length > 5">
              <i class="iconfont icon-xiangzuo-copy"></i>
            </div>
            <div class="swiper-btn swiper-button-next" slot="button-next" v-show="iconListData.length > 5">
              <i class="iconfont icon-xiangyou"></i>
            </div>
          </div>
        </div>
        <div class="clear-fix"></div>
        <el-form-item label="镜像简介：" prop="MirrorDesc">
          <el-input type="textarea" v-model="MirrorForm.MirrorDesc" maxlength="200" @input="MirrorDescInput"></el-input>
          <p style="position:absolute; left: 610px; bottom: 0px; color:#bbb;">
            {{MirrorForm.MirrorDescNum}}/200</p>
        </el-form-item>

        <div class="footer" style="text-align:center;">
          <el-button class="button-style saveBtn" @click="ModifyMirrorFormSave('MirrorForm')">保存</el-button>
        </div>
      </el-form>
    </el-dialog>
    <!-- 重选配置 -->
    <el-dialog :close-on-click-modal="false" class="dialog-distribution" title="重选配置" :visible.sync="dialogDistributionFormVisible" label-width="100px" width="830px">
      <el-form :model="distributionform" ref="distributionform">
        <el-form-item class="is-required" label="实验类型：">
          <el-radio-group v-model="distributionform.experimentType" @change="experimentTypeChange">
            <el-radio :label="1">可视化实验</el-radio>
            <!-- <el-radio :label="2">NoteBook实验</el-radio> -->
          </el-radio-group>
        </el-form-item>
        <el-form-item class="is-required" label="配置类型：" v-if="distributionform.experimentType == 1">
          <el-radio-group v-model="distributionform.resource">
            <el-radio :label="1">单节点</el-radio>
            <el-radio :label="2">集群</el-radio>
          </el-radio-group>
        </el-form-item>
        <template v-if="distributionform.experimentType == 2">
          <el-form-item class="config-item">
            <div class="fl item-config">
              <el-form-item prop="distributedData.cpuValue" :rules="{
                                    required: true, message: '请选择CPU上限', trigger: 'blur'
                                }" label="配置：" style=" float:left; width:210px;" class="item-cpu">
                <el-select v-model="distributionform.distributedData.cpuValue" value-key="value" placeholder="CPU上限">
                  <el-option v-for="item in distributionform.distributedData.cpuOptions" :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item prop="distributedData.ramValue" :rules="{
                                    required: true, message: '请选择内存上限', trigger: 'blur'
                                }" style="width:110px; float:left; margin-left:10px;">
                <el-select v-model="distributionform.distributedData.ramValue" placeholder="内存上限">
                  <el-option v-for="item in distributionform.distributedData.ramOptions" :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
            </div>
          </el-form-item>
          <el-form-item class="is-required" label="镜像：">
            <el-cascader :options="distributionform.options0" v-model="distributionform.optionsValue0" :show-all-levels="false" @change="handleItemChange"></el-cascader>
          </el-form-item>
        </template>
        <template v-if="distributionform.experimentType == 1">
          <div class="form-title">
            {{ distributionform.resource == 1 ? '伪分布' : '主节点'}}</div>
          <!-- 伪分布 -->
          <el-form-item class="config-item" v-if="distributionform.resource == 1">
            <div class="fl item-config">
              <el-form-item prop="distributedData.cpuValue" :rules="{
                                    required: true, message: '请选择CPU上限', trigger: 'blur'
                                }" label="配置：" style=" float:left; width:210px;" class="item-cpu">
                <el-select v-model="distributionform.distributedData.cpuValue" value-key="value" placeholder="CPU上限">
                  <el-option v-for="item in distributionform.distributedData.cpuOptions" :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item prop="distributedData.ramValue" :rules="{
                                    required: true, message: '请选择内存上限', trigger: 'blur'
                                }" style="width:110px; float:left; margin-left:10px;">
                <el-select v-model="distributionform.distributedData.ramValue" placeholder="内存上限">
                  <el-option v-for="item in distributionform.distributedData.ramOptions" :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
            </div>
            <!-- <el-form-item class="fl item-Gpu" label="GPU">
                            <el-switch
                                v-model="distributionform.distributedData.switchValue">
                            </el-switch>
                        </el-form-item> -->
          </el-form-item>
          <el-form-item class="is-required" label="镜像：" v-if="distributionform.resource == 1">
            <el-cascader :options="distributionform.options0" v-model="distributionform.optionsValue0" :show-all-levels="false" @change="handleItemChange"></el-cascader>
          </el-form-item>
          <!-- 伪分布end -->
          <!-- 主节点 -->
          <el-form-item class="config-item" v-if="distributionform.resource == 2">
            <div class="fl item-config">
              <el-form-item prop="nodeMianData.cpuValue" :rules="{
                                    required: true, message: '请选择CPU上限', trigger: 'blur'
                                }" label="配置：" style=" float:left; width:210px;" class="item-cpu">
                <el-select v-model="distributionform.nodeMianData.cpuValue" value-key="value" placeholder="CPU上限">
                  <el-option v-for="item in distributionform.nodeMianData.cpuOptions" :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item prop="nodeMianData.ramValue" :rules="{
                                    required: true, message: '请选择内存上限', trigger: 'blur'
                                }" style="width:110px; float:left; margin-left:10px;">
                <el-select v-model="distributionform.nodeMianData.ramValue" placeholder="内存上限">
                  <el-option v-for="item in distributionform.nodeMianData.ramOptions" :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
            </div>
            <!-- <el-form-item class="fl item-Gpu" label="GPU">
                            <el-switch
                                v-model="distributionform.nodeMianData.switchValue">
                            </el-switch>
                        </el-form-item> -->
          </el-form-item>
          <el-form-item class="is-required" label="镜像：" v-if="distributionform.resource == 2">
            <el-cascader :options="distributionform.options7" v-model="distributionform.optionsValue7" :show-all-levels="false" @change="handleItemChange"></el-cascader>
          </el-form-item>
          <!-- 伪分布end -->
          <div class="form-title" v-if="distributionform.resource == 2">从节点</div>
          <!-- 镜像配置 -->
          <el-form-item class="config-item" v-if="distributionform.resource == 2">
            <div class="fl item-config">
              <el-form-item prop="mirrorConfigData.cpuValue" :rules="{
                                    required: true, message: '请选择CPU上限', trigger: 'blur'
                                }" label="配置：" style=" float:left; width:210px;" class="item-cpu">
                <el-select v-model="distributionform.mirrorConfigData.cpuValue" value-key="value" placeholder="CPU上限">
                  <el-option v-for="item in distributionform.mirrorConfigData.cpuOptions" :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item prop="mirrorConfigData.ramValue" :rules="{
                                    required: true, message: '请选择内存上限', trigger: 'blur'
                                }" style="width:110px; float:left; margin-left:10px;">
                <el-select v-model="distributionform.mirrorConfigData.ramValue" placeholder="内存上限">
                  <el-option v-for="item in distributionform.mirrorConfigData.ramOptions" :key="item.value" :label="item.label" :value="item.value">
                  </el-option>
                </el-select>
              </el-form-item>
            </div>
            <!-- <el-form-item class="fl item-Gpu" label="GPU">
                            <el-switch
                                v-model="distributionform.mirrorConfigData.switchValue">
                            </el-switch>
                        </el-form-item> -->
          </el-form-item>
          <!-- 镜像配置 -->
          <el-form-item v-if="distributionform.resource == 2" label="从节点数：">
            <div class="virtual-step">
              <ul>
                <!-- <li v-for="(item, index) in distributionform.virtualStepList" @click="AddClass(((index+1)*2))" :class="{ active:((index+1)*2) == distributionform.virtualStepCurrent, 'active-disabled': index != 0}">{{item.value}}</li> -->
                <li v-for="(item, index) in distributionform.virtualStepList" @click="AddClass(((index+1)))" :class="{ active:((index+1)) == distributionform.virtualStepCurrent}">{{item.value}}</li>
              </ul>
            </div>
          </el-form-item>
          <div class="item-node" v-if="distributionform.resource == 2">
            <el-form-item class="is-required" label="镜像1：" v-if="distributionform.virtualStepCurrent == 1 || distributionform.virtualStepCurrent == 2 ||distributionform.virtualStepCurrent == 4 || distributionform.virtualStepCurrent == 6">
              <el-cascader :options="distributionform.options1" v-model="distributionform.optionsValue1" :show-all-levels="false" @change="handleItemChange"></el-cascader>
            </el-form-item>
            <el-form-item class="is-required" label="镜像2：" v-if="distributionform.virtualStepCurrent == 2 || distributionform.virtualStepCurrent == 4 || distributionform.virtualStepCurrent == 6">
              <el-cascader :options="distributionform.options2" v-model="distributionform.optionsValue2" :show-all-levels="false" @change="handleItemChange"></el-cascader>
            </el-form-item>
            <el-form-item class="is-required" label="镜像3：" v-if="distributionform.virtualStepCurrent == 4 || distributionform.virtualStepCurrent == 6">
              <el-cascader :options="distributionform.options3" v-model="distributionform.optionsValue3" :show-all-levels="false" @change="handleItemChange"></el-cascader>
            </el-form-item>
            <el-form-item class="is-required" label="镜像4：" v-if="distributionform.virtualStepCurrent == 4 || distributionform.virtualStepCurrent == 6">
              <el-cascader :options="distributionform.options4" v-model="distributionform.optionsValue4" :show-all-levels="false" @change="handleItemChange"></el-cascader>
            </el-form-item>
            <el-form-item class="is-required" label="镜像5：" v-if="distributionform.virtualStepCurrent == 6">
              <el-cascader :options="distributionform.options5" v-model="distributionform.optionsValue5" :show-all-levels="false" @change="handleItemChange"></el-cascader>
            </el-form-item>
            <el-form-item class="is-required" label="镜像6：" v-if="distributionform.virtualStepCurrent == 6">
              <el-cascader :options="distributionform.options6" v-model="distributionform.optionsValue6" :show-all-levels="false" @change="handleItemChange"></el-cascader>
            </el-form-item>
          </div>
        </template>
      </el-form>
      <div class="distribution-item" v-if="distributionform.distributionData">
        <div class="jx-course-box">
          <img :src="distributionform.distributionData.iconUrl" />
          <span v-text="distributionform.distributionData.imageName"></span>
        </div>
        <div class="jx-course-text" v-text="distributionform.distributionData.description"></div>
        <div class="jx-course-icon" v-if="distributionform.distributionData.gpu">
          <img src="./../../../assets/images/gpu_icon.png" />
        </div>
        <div class="jx-course-icon" v-if="distributionform.distributionData.notebook">
          <img src="./../../../assets/images/notebook_icon.png" />
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button class="button-style" @click="DistributionFormSave('distributionform')">保 存</el-button>
      </div>
    </el-dialog>
    <!-- 初始化弹窗 -->
    <el-dialog :close-on-click-modal="false" class="dialog-init-virtual" title="提示" :visible.sync="dialogInitVirtual" width="460px">
      <div class="dialog-content">
        <p>初始化会丢失文件、数据，确定要初始化吗?</p>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button class="button-style" @click="dialogInitVirtual = false">取 消</el-button>
        <el-button class="button-style" @click="DialogInitVirtualSave(0)">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import mavonEditor from '../../../components/mavonEditor'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import Time from '../../../components/Time'
import {
  getJudgeListCP,
  addOrModifyJudgeCP,
  deleJudgeCP,
  getTaskAndAnswerInfoCP,
  modifyTaskAndAnswerInfoCP,
  getOnesInfoCP,
} from '@/api/competitionPlatform'
export default {
  name: 'ModifyVirtualMachine',

  components: {
    mavonEditor,
    swiper,
    swiperSlide,
    Time,
  },
  data() {
    return {
      // 修改时判定得分时，用于验证是否超出总分
      itemScore: 0, //在点击修改时赋值，只在 验证总分 的方法里使用
      //该任务的总分
      taskTotalScore: 0,
      //nav切换
      navIndex: 1,
      //判定条件设置的得分不符合时，弹出警告
      warning: '',
      // 判定条件添加开关
      add_on_off: false,
      //添加和修改情况下显示不同的判断规则序号
      add_or_amend: true,
      //用来标记判定规则  比如"判定规则1""判定规则2"
      nameNumber: 0,
      // 参考答案
      markHtml: '',
      content: '',
      //竞赛题目
      TargetContent: '',
      TargetMarkHtml: '',
      //单独领出来做验证，防止bug情况出现
      judgeType: 1,
      //添加提交的form表单
      form: {
        //后台规定写死为1
        type: 1,
        //任务id
        contextId: 0,
        // "id": 3, //判定id【如果传这个字段 代表修改；如果不传这个字段，代表添加】
        //判定得分
        score: 0,
        // 判定题目
        examQuestion: '',
        //判定类型 1: 环境安装/进程检查 2：单数值 3：字符串/数组/集合
        judgeType: 1,
        //判定输出结果
        answer: '',
        //当judgeType为1时，则 answerRuleType为1代表：内容一致（不要求顺序）   为 2代表：输出结果包含判定结果  ;
        //当judgeType为2时，则 answerRuleType为1代表：完全一致              ，为 2代表：数值趋近；
        //当judgeType为2时，则 answerRuleType为1代表：完全一致                为2代表：内容一致（不要求顺序）    为3代表： 数值趋近
        answerRuleType: 1,
        //代码执行脚本
        script: '',
        //脚本类型 1：脚本  2：文件比对路径
        scriptType: 1,
        //集合数值趋近 误差范围
        numberParam: [
          {
            numberParamErrorValueBefore: 0, //允许前误差值
            numberParamErrorValueAfter: 0, //允许后误差值
            rowNum: 1, //行数
            columnNum: 1, //列数
          },
        ],
      },
      //把最初的form转成str留样，方便随时恢复干净的form表单
      formStr: '',
      //判定条件列表
      judgeList: [],

      // 浏览器分辨率
      ScreenSigma: '',
      // 桌面loading
      deskLoading: false,
      deskLoadingText: '桌面加載中',
      contentLoading: null,
      // 角色
      roles: '',
      // 课程ID
      courseId: '',
      // 章节ID
      chapterId: '',
      // 课程名称
      courseName: '',
      // 虚机信息
      VirtualMachineInfo: '',
      // 虚机全屏fullScreen
      fullScreen: false,
      // 虚机地址
      VirtualMachineUrl: '',
      VirtualMachineUrlArr: [],
      // 虚机当前ID数组
      VirtualMachineIdArr: [],
      // 虚机当前容器ID
      VirtualMachineId: '',
      // 虚机当前镜像ID
      VirtualImageId: '',
      iframeHeight: '',
      // 虚机切换导航列表
      virtualMachineNavList: [],
      // 虚机导航列表index
      MachineNavTabIndex: '0',
      // 虚拟机id
      containerId: '',
      toolbarsMav: {
        bold: true, // 粗体
        italic: false, // 斜体
        header: true, // 标题
        // underline: true, // 下划线
        // strikethrough: true, // 中划线
        // mark: true, // 标记
        // superscript: true, // 上角标
        // subscript: true, // 下角标
        quote: true, // 引用
        ol: true, // 有序列表
        ul: true, // 无序列表
        imagelink: true, // 图片链接
        code: true, // code
        table: true, // 表格
        help: true, // 帮助
        alignleft: true, // 左对齐
        aligncenter: true, // 居中
        alignright: true, // 右对齐
        preview: true, // 预览
        fullscreen: true, // 全屏编辑
      },
      // 重选配置弹窗
      dialogDistributionFormVisible: false,
      distributionform: {
        // 类型
        resource: 1,
        // 实验类型 1 可视化实验 2 notebook实验
        experimentType: 1,
        // 伪分布数组
        distributedData: {
          // cpu配置
          cpuOptions: [
            {
              value: '1',
              label: '1核',
            },
            {
              value: '2',
              label: '2核',
            },
            {
              value: '4',
              label: '4核',
            },
            {
              value: '6',
              label: '6核',
            },
            {
              value: '8',
              label: '8核',
            },
            {
              value: '10',
              label: '10核',
            },
          ],
          cpuValue: '',
          ramOptions: [
            {
              value: '1',
              label: '1G',
            },
            {
              value: '2',
              label: '2G',
            },
            {
              value: '4',
              label: '4G',
            },
            {
              value: '6',
              label: '6G',
            },
            {
              value: '8',
              label: '8G',
            },
            {
              value: '10',
              label: '10G',
            },
            {
              value: '12',
              label: '12G',
            },
            {
              value: '14',
              label: '14G',
            },
            {
              value: '16',
              label: '16G',
            },
            {
              value: '32',
              label: '32G',
            },
            {
              value: '48',
              label: '48G',
            },
            {
              value: '64',
              label: '64G',
            },
          ],
          ramValue: '',
          // GPU
          // switchValue: false
        },
        // 镜像配置
        mirrorConfigData: {
          // cpu配置
          cpuOptions: [
            {
              value: '1',
              label: '1核',
            },
            {
              value: '2',
              label: '2核',
            },
            {
              value: '4',
              label: '4核',
            },
            {
              value: '6',
              label: '6核',
            },
            {
              value: '8',
              label: '8核',
            },
            {
              value: '10',
              label: '10核',
            },
          ],
          cpuValue: '',
          ramOptions: [
            {
              value: '1',
              label: '1G',
            },
            {
              value: '2',
              label: '2G',
            },
            {
              value: '4',
              label: '4G',
            },
            {
              value: '6',
              label: '6G',
            },
            {
              value: '8',
              label: '8G',
            },
            {
              value: '10',
              label: '10G',
            },
            {
              value: '12',
              label: '12G',
            },
            {
              value: '14',
              label: '14G',
            },
            {
              value: '16',
              label: '16G',
            },
            {
              value: '32',
              label: '32G',
            },
            {
              value: '48',
              label: '48G',
            },
            {
              value: '64',
              label: '64G',
            },
          ],
          ramValue: '',
          // GPU
          switchValue: false,
        },
        // 主节点
        nodeMianData: {
          // cpu配置
          cpuOptions: [
            {
              value: '1',
              label: '1核',
            },
            {
              value: '2',
              label: '2核',
            },
            {
              value: '4',
              label: '4核',
            },
            {
              value: '6',
              label: '6核',
            },
            {
              value: '8',
              label: '8核',
            },
            {
              value: '10',
              label: '10核',
            },
          ],
          cpuValue: '',
          ramOptions: [
            {
              value: '1',
              label: '1G',
            },
            {
              value: '2',
              label: '2G',
            },
            {
              value: '4',
              label: '4G',
            },
            {
              value: '6',
              label: '6G',
            },
            {
              value: '8',
              label: '8G',
            },
            {
              value: '10',
              label: '10G',
            },
            {
              value: '12',
              label: '12G',
            },
            {
              value: '14',
              label: '14G',
            },
            {
              value: '16',
              label: '16G',
            },
            {
              value: '32',
              label: '32G',
            },
            {
              value: '48',
              label: '48G',
            },
            {
              value: '64',
              label: '64G',
            },
          ],
          ramValue: '',
          // GPU
          switchValue: false,
        },
        options0: [],
        optionsValue0: [],
        options1: [],
        optionsValue1: [],
        options2: [],
        optionsValue2: [],
        options3: [],
        optionsValue3: [],
        options4: [],
        optionsValue4: [],
        options5: [],
        optionsValue5: [],
        options6: [],
        optionsValue6: [],
        options7: [],
        optionsValue7: [],
        virtualStepList: [{ value: 1 }, { value: 2 }],
        virtualStepCurrent: 1,
        // 镜像列表数据
        distributionData: '',
      },
      // 镜像保存弹窗轮播组件data
      iconListData: '',
      swiperDialogOption: {
        slidesPerView: 5,
        spaceBetween: 24,
        initialSlide: 1,
        loop: false,
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev',
        },
      },
      // 镜像保存弹窗
      dialogMirrorInfo: false,
      // 镜像弹窗保存方式是否显示
      saveWayStatus: false,
      // 镜像保存OR创建
      VirtualSelf: '',
      // 镜像保存表单
      MirrorForm: {
        // 镜像名称
        MirrorName: '',
        // 保存镜像方式
        saveWay: 1,
        // 镜像名称长度
        MirrorNameNum: 50,
        // 镜像简介
        MirrorDesc: '',
        // 镜像简介长度
        MirrorDescNum: 200,
        // 选中的镜像图标ID
        iconId: '',
        // 镜像ID
        imageId: '',
      },
      MirrorFormRules: {
        MirrorName: [
          { required: true, message: '请输入镜像名称', trigger: 'blur' },
        ],
        MirrorDesc: [
          { required: true, message: '请输入镜像简介', trigger: 'blur' },
        ],
      },
      // 关闭分享
      dialogCloseShare: false,
      // 实验截图
      dialogScreenshot: false,
      dialogScreenshotCopyUrl: '',
      // 实验截图url
      dialogScreenshotUrl: '',
      // 学生手册
      dialogHandbook: false,
      //竞赛题目和 参考答案开关
      dialogHandbookDrag1: false,
      dialogHandbookDrag2: false,
      // sftp
      dialogSftp: false,
      // Sftp ip
      sftpIp: '',
      sftpPort: '',
      sftpHost: '',
      // 剪切板dialog
      dialogCut: false,
      cutData: {
        cutRuleForm: {
          desc: '',
          descNum: 20000,
        },
        cutRules: {
          desc: [{ required: true, message: '请填写内容', trigger: 'blur' }],
        },
      },
      // 文件上传dialog
      dialogFileUpload: false,
      FileUploadForm: {
        fileName: '',
        versionFile: '',
      },
      FileUploadRules: {
        versionFile: [
          { required: true, message: '请上传文件', trigger: 'blur' },
        ],
      },
      val: '123',
      // 虚机右侧导航
      mirrorRightWidth: 0,

      // 用户退出删除虚机socket
      UserOutWebsock: null,
      UserOutWebsockOver: null,

      // 初始化弹窗
      dialogInitVirtual: false,
      // 错误提示
      mirrorIframeTip: false,
      mirrorIframeTipText: '',

      // 二期新增
      // gpu状态
      gpuStatus: '',
      // notebook状态
      notebookStatus: '',

      // 专科版本增加
      // 任务id

      taskId: '',
      // 是否是步骤
      stepTypeStr: '',
      stepList: [],
      stepListIndex: 0,
      // 任务名称
      taskName: '',
    }
  },
  created() {
    let self = this
    // 登录角色 ''未登录 TEACHER 教师 ADMIN管理员 STUDENT学生
    self.roles = self.$store.state.user.roles[0]
    // 课程ID
    // self.courseId = self.$localstorage.getLocalStorage('setCourseId')
    self.courseId = self.$route.query.courseId
    // 章节ID
    self.chapterId = self.$route.query.chapterId
    //
    this.taskId = this.$route.query.taskId
    // 给可能提交的判定规则form表单设置好任务id
    this.form.contextId = this.taskId

    // 专科版本更改
    // 需求：原来的chapterId要换成任务id
    let manyExperiment =
      self.$localstorage.getLocalStorage('chapterInfoData').manyExperiment
    // 是否是多步骤
    self.stepTypeStr =
      self.$localstorage.getLocalStorage('chapterInfoData').stepTypeStr

    self.ScreenSigma = (window.screen.width / window.screen.height).toFixed(2)
    self.$nextTick(function () {
      self.iframeHeight = $(window).height() - 60
      $('.mirror-iframe, .step-main-mirror').width(
        (1024 / 768) * ($(window).height() - 60)
      )
      $('.jx-virtual-machine-main').height(self.iframeHeight)
      $('.step-main-content').width(
        $(window).width() - $('.step-main-mirror').width()
      )
      window.onresize = function () {
        if (self.fullScreen) {
          $('.step-main-mirror').width(
            ($(window).width() / self.iframeHeight) * self.iframeHeight
          )
          setTimeout(() => {
            $('.mirror-iframe').width($('.step-main-mirror').width() - 1)
          }, 1000)
        } else {
          self.iframeHeight = $(window).height() - 60
          $('.mirror-iframe, .step-main-mirror').width(
            (1024 / 768) * self.iframeHeight
          )
          $('.jx-virtual-machine-main').height(self.iframeHeight)
          $('.step-main-content').width(
            $(window).width() - $('.step-main-mirror').width()
          )
        }
      }
      // if(window.screen.width <= 1280){
      //     self.fullScreen = true
      //     $(".step-main-mirror").width(($(window).width() / self.iframeHeight) * self.iframeHeight)
      //     setTimeout(() => {
      //         $('.mirror-iframe').width($(".step-main-mirror").width())
      //     }, 1000);
      // }

      // 设置编辑器高度
      $('.step-main-editor').css({
        height: $(window).height() - 220 + 'px',
      })
      $('.jx-main-content').css({
        height: $(window).height() - 120 + 'px',
      })
      $('.step-main-editor .v-note-wrapper').css({
        height: '100%',
        'z-index': '1',
      })
    })
    // 初始化学习手册
    // if (self.stepTypeStr != '多步骤实验') {
    self.getTaskAndAnwser()
    // }
    // 初始化进入实验
    self.InitExperiment(0)

    // 初始化socket
    // self.InitWebSocket()

    // 初始化头部信息
    self.InitHeaderInfo()

    // 用户退出删除虚机socket
    self.InitUserOutWebSocket()

    //获取判定规则列表
    this.getJudgeList()
    //把最初的form转成str留样，方便随时恢复干净的form表单
    this.formStr = JSON.stringify(this.form)
    // 获取任务总分
    this.getTaskInfo()
  },
  mounted() {
    this.$refs.question.toolbars = this.toolbarsMav
    this.$refs.question.toolbars = this.toolbarsMav
    $('#spaceHeight').height($(window).height() - 130)
  },
  watch: {
    judgeType() {
      this.form.judgeType = this.judgeType
      this.form.answerRuleType = 1
    },
  },
  methods: {
    // 获取任务总分
    getTaskInfo() {
      getOnesInfoCP(this.courseId, this.chapterId)
        .then((res) => {
          if (res.code == 200) {
            this.taskTotalScore = res.data.score
          } else {
            this.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 判定规则前后误差验证
    inputJudge1(e) {
      var val = e.target.value
      //限制只能输入一个小数点
      if (val.indexOf('.') != -1) {
        var str = val.substr(val.indexOf('.') + 1)
        if (str.indexOf('.') != -1) {
          val = val.substr(0, val.indexOf('.') + str.indexOf('.') + 1)
        }
      }
      e.target.value = val.replace(/[^\d^\.]+/g, '')
    },
    // 判定规则前后误差验证
    inputJudge2(value, index, name) {
      this.form.numberParam[index][name] =
        ('' + value) // 第一步：转成字符串
          .replace(/[^\d^\.]+/g, '') // 第二步：把不是数字，不是小数点的过滤掉
          .replace(/^0+(\d)/, '$1') // 第三步：第一位0开头，0后面为数字，则过滤掉，取后面的数字
          .replace(/^\./, '0.') // 第四步：如果输入的第一位为小数点，则替换成 0. 实现自动补全
          .match(/^\d*(\.?\d{0,20})/g)[0] || '' // 第五步：最终匹配得到结果 以数字开头，只有一个小数点，而且小数点后面只能有0到2位小数
    },
    //导航切换
    MachineNavTab(index) {
      this.navIndex = index
    },
    //获取判定条件列表
    getJudgeList() {
      getJudgeListCP(this.taskId)
        .then((res) => {
          if (res.code == '200') {
            this.judgeList = res.data
          } else {
            // self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 新增判断条件
    addJudge() {
      const loading = this.$loading({
        lock: true,
        text: '加载中',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      this.form = JSON.parse(this.formStr)
      this.add_on_off = true
      this.add_or_amend = true
      this.itemScore = 0
      loading.close()
    },
    //修改判定规则
    amendJudge(amendForm, index) {
      const loading = this.$loading({
        lock: true,
        text: '加载中',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      // 记录这是第几个判定规则
      this.nameNumber = index + 1
      // 修改时的一些显示开关
      this.add_or_amend = false
      this.add_on_off = true
      //记录最开始的分数，方便做总分验证
      this.itemScore = parseFloat(amendForm.score)
      //复制相同的数据到form表单，填入修改时需要的字段，方便后续提交
      this.judgeType = amendForm.judgeType
      this.form = JSON.parse(JSON.stringify(amendForm))
      this.form.type = 1
      this.form.contextId = this.taskId
      if (
        this.form.numberParam == undefined ||
        this.form.numberParam.length == 0
      ) {
        this.$set(this.form, 'numberParam', [
          {
            numberParamErrorValueBefore: 0, //允许前误差值
            numberParamErrorValueAfter: 0, //允许后误差值
            rowNum: 1, //行数
            columnNum: 1, //列数
          },
        ])
      }

      loading.close()
    },
    // 删除判定规则
    async deleteJudge(id) {
      await this.$confirm('是否删除该规则?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          return deleJudgeCP({ ids: [id], courseId: this.courseId })
        })
        .then((res) => {
          if (res.code == '200') {
            this.$alert('删除成功', '提示', {
              confirmButtonText: '确定',
            })
          } else {
            this.$message.error(res.data.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
      //重新获取一下列表
      this.getJudgeList()
      this.itemScore = 0
    },
    // 取消新增
    cancelJudge() {
      const loading = this.$loading({
        lock: true,
        text: '加载中',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      this.add_on_off = false
      this.warning = ''
      this.form.score = 0
      // this.getJudgeList();
      this.itemScore = 0
      loading.close()
    },
    // 保存判断条件
    async saveJudge() {
      this.form.judgeType = this.judgeType
      if (this.warning != '' || this.form.score == 0) {
        this.$alert('该判定规则得分错误,请重新填写')
        return
      }
      if (this.form.examQuestion == '') {
        this.$alert('请输入判定题目')
        return
      }
      // if (this.form.answer.length > 1000 || this.form.answer.length == 0) {
      //   this.$alert(
      //     '判定输出结果限制1-2000字符，现在有' +
      //       this.form.answer.length +
      //       '字符'
      //   )
      //   return
      // }
      // if (this.form.script.length > 1000 || this.form.script.length == 0) {
      //   this.$alert(
      //     '校验脚本限制1-1000字符，现在有' + this.form.script.length + '字符'
      //   )
      //   return
      // }
      await this.$confirm('是否保存该规则?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      })
        .then(() => {
          return addOrModifyJudgeCP(this.form)
        })
        .then((res) => {
          if (res.code == '200') {
            this.$message({
              type: 'success',
              message: '保存成功',
            })
            this.getJudgeList()
            this.itemScore = 0
            this.add_on_off = false
          } else {
            return this.$message.error(res.data.message)
          }
        })
        .catch((err) => {
          //  this.$message.error(err);
          console.log(err)
        })
    },
    // 增加误差判断范围
    addErrorCondition() {
      if (this.form.numberParam === undefined) {
        this.form.numberParam = []
      } else {
        this.form.numberParam.push({
          numberParamErrorValueBefore: 0, //允许前误差值
          numberParamErrorValueAfter: 0, //允许后误差值
          rowNum: 1, //行数
          columnNum: 1, //列数
        })
      }
    },
    // 删除误差判断范围
    canceErrorCondition(index) {
      this.form.numberParam.pop()
    },
    //抬起判定任务总分是否超出
    checkScore() {
      this.form.score = this.form.score.replace(/[^0-9]/g, '')
      // 记录修改时所有任务加起来的总分
      let nowTotal = parseFloat(this.form.score)
      let nowTotal2 = 0
      this.judgeList.map((item) => {
        nowTotal += item.score
        nowTotal2 += item.score
      })
      //this.itemScore这个属性记录的是 点击修改的判定规则 修改前的分数
      // 总分 < 修改时的任务总分 - 原来的任务分   时报错
      if (this.taskTotalScore < nowTotal - this.itemScore) {
        let num =
          parseInt(this.taskTotalScore) + parseInt(this.itemScore) - nowTotal2
        this.warning =
          '各判定规则之和不得超过任务分数，当前规则最大' + num + '分'
      } else if (this.form.score <= 0) {
        this.warning = '规则分数不能小于0'
      } else {
        this.warning = ''
      }
    },
    //获取竞赛题目和参考答案
    getTaskAndAnwser() {
      getTaskAndAnswerInfoCP(this.courseId, this.taskId).then((res) => {
        if (res.code == '200') {
          //竞赛题目
          if (
            res.data.laboratoryTarget.creativeVersion != undefined &&
            res.data.laboratoryTarget.creativeVersion.length > 0
          ) {
            this.$refs.question.value =
              res.data.laboratoryTarget.creativeVersion[0].content
          }
          //参考答案
          if (
            res.data.laboratoryManual.creativeVersion != undefined &&
            res.data.laboratoryManual.creativeVersion.length > 0
          ) {
            this.$refs.referenceAnswer.value =
              res.data.laboratoryManual.creativeVersion[0].content
          }
        } else {
          this.$message.error(res.message)
        }
      })
    },
    // 竞赛题目和参考答案保存，1是竞赛题目，2是参考答案
    noteSubmit(tag, flag) {
      // tag区分左侧(1)还是弹窗(2)
      // flag区分是竞赛题目(1)还是参考答案(2)
      let self = this
      let data = {}
      let url = ''
      if (tag == 1) {
        if (flag == 1) {
          url = `/tes/course/${this.courseId}/chapter/${this.taskId}/resource-online?resourceType=14`
          data.name = '任务说明'
          data.content = self.$refs.question.value
          data.htmlContent = self.$refs.question.getRender()
        } else {
          url = `/tes/course/${this.courseId}/chapter/${this.taskId}/resource-online?resourceType=8`
          data.name = '参考答案'
          data.content = self.$refs.referenceAnswer.value
          data.htmlContent = self.$refs.referenceAnswer.getRender()
        }
      } else {
        if (flag == 1) {
          url = `/tes/course/${this.courseId}/chapter/${this.taskId}/resource-online?resourceType=14`
          data.name = '任务说明'
          data.content = self.$refs.TheProblem.value
          data.htmlContent = self.$refs.TheProblem.getRender()
        } else {
          url = `/tes/course/${this.courseId}/chapter/${this.taskId}/resource-online?resourceType=8`
          data.name = '参考答案'
          data.content = self.$refs.TheAnswer.value
          data.htmlContent = self.$refs.TheAnswer.getRender()
        }
      }

      modifyTaskAndAnswerInfoCP(url, data)
        .then((res) => {
          if (res.code == '200') {
            this.$message({
              message: '保存成功',
              type: 'success',
            })
            this.getTaskAndAnwser()
          } else {
            this.$message.error(res.data.message)
          }
        })
        .catch((err) => console.log(err))
    },
    //竞赛题目参考答案弹窗
    HandbookDialog(n) {
      let self = this
      if (n == 1) {
        self.dialogHandbookDrag1 = true
        getTaskAndAnswerInfoCP(this.courseId, this.taskId).then((res) => {
          if (res.code == '200') {
            //竞赛题目
            if (
              res.data.laboratoryTarget.creativeVersion != undefined &&
              res.data.laboratoryTarget.creativeVersion.length > 0
            ) {
              this.$refs.TheProblem.value =
                res.data.laboratoryTarget.creativeVersion[0].content
            }
          } else {
            this.$message.error(res.message)
          }
        })
      } else if (n == 2) {
        self.dialogHandbookDrag2 = true
        getTaskAndAnswerInfoCP(this.courseId, this.taskId).then((res) => {
          if (res.code == '200') {
            //参考答案
            if (
              res.data.laboratoryManual.creativeVersion != undefined &&
              res.data.laboratoryManual.creativeVersion.length > 0
            ) {
              this.$refs.TheAnswer.value =
                res.data.laboratoryManual.creativeVersion[0].content
            }
          } else {
            this.$message.error(res.message)
          }
        })
      }
    },
    // 通知webSocket
    InitWebSocket() {
      const wsuri = 'ws://172.16.100.182:9999/tes/global'
      this.websock = new WebSocket(wsuri)
      this.websock.onopen = this.websocketonopen
      this.websock.onmessage = this.websocketonmessage
      this.over = () => {
        this.websock.close()
      }
    },
    websocketonopen() {
      console.log('open sucess')
    },
    websocketonmessage(e) {
      // 数据接收
      const redata = JSON.parse(e.data)
      let redataJson = {}
    },
    // 用户退出删除虚机socket
    InitUserOutWebSocket() {
      let self = this
      let hostname = window.location.host
      const wsuri =
        'ws://' + hostname + '/tes/ws/image-allocation/course/' + self.taskId
      self.UserOutWebsock = new WebSocket(wsuri)
      self.UserOutWebsock.onopen = self.UserOutwebsocketonopen
      self.UserOutWebsock.onmessage = self.UserOutwebsocketonmessage
      self.UserOutWebsockOver = () => {
        self.UserOutWebsock.close()
      }
    },
    UserOutwebsocketonopen() {
      console.log('open sucess')
    },
    UserOutwebsocketonmessage() {
      const redata = JSON.parse(e.data)
      let redataJson = {}
    },
    mask() {
      $('.mask').css('opacity', '1')
      $('.mask').css('display', 'block')
      $('.mask-bg').css('left', '0')
    },
    closeMask() {
      let timer
      clearInterval(timer)
      $('.mask-bg').css('left', '-100%')
      timer = setTimeout(() => {
        $('.mask').css('opacity', '0')
        $('.mask').css('display', 'none')
      }, 300)
    },
    // 退出虚机
    DropoutVirtual() {
      let self = this
      self
        .$confirm('确定退出虚机吗?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        })
        .then(() => {
          this.$router.push({
            path: '/TaskDetails',
            query: {
              courseId: this.courseId,
              taskId: this.taskId,
              chapterId: this.chapterId,
            },
          })
        })
        .catch(() => {})
    },
    // 初始化头部信息
    InitHeaderInfo() {
      let self = this
      self.$http
        .get('/tes/course/' + self.courseId + '/chapter/' + self.taskId)
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            // 课程名称
            self.courseName = res.data.courseName
            // 章节名称
            self.taskName = res.data.chapterName
          } else {
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 初始化进入实验
    InitExperiment(index) {
      // index 虚机index
      let self = this
      self.fullScreen = false

      self.deskLoading = true
      self.deskLoadingText = '桌面加載中'
      self.VirtualMachineUrl = ''

      self.VirtualMachineUrlArr = []
      // 清空虚机切换列表导航集合
      self.VirtualMachineIdArr = []
      self.virtualMachineNavList = []
      self.$http
        .get('/tes/image-allocation/course/' + self.taskId + '/experiment')
        .then((response) => {
          let res = response.data

          if (res.code == '200') {
            // 初始化虚拟机信息
            self.VirtualMachineInfo = res.data
            self.mirrorIframeTip = false
            // setTimeout(() => {
            //     self.iframeHeight = $(window).height() - 60
            //     $(".mirror-iframe, .step-main-mirror").width((1024 / 768) * ($(window).height() - 60))
            //     $('.jx-virtual-machine-main').height(self.iframeHeight)
            //     $(".step-main-content").width($(window).width() - $(".step-main-mirror").width())
            // }, 800);

            // 虚机容器ID
            self.VirtualMachineId = res.data[index].containerId
            // 虚机镜像id
            self.VirtualImageId = res.data[index].imageId

            self.fullScreen = false
            let fullData = []
            for (let i = 0; i < res.data.length; i++) {
              self.VirtualMachineIdArr.push(res.data[i].containerId)
              // 虚机切换列表导航集合
              self.virtualMachineNavList.push(res.data[i].containerRole)
              // 如果含有全屏状态
              // if(res.data[i].fullScreen){
              //     fullData.push(res.data[i].containerId)
              //     self.VirtualFullScreen(1,fullData)
              // }
              fullData.push(res.data[i].containerId)
            }
            if (res.data[0].fullScreen && !res.data[0].notebook) {
              self.VirtualFullScreen(1, fullData)
            }
            if (res.data[0] && res.data[0].notebook) {
              self.fullScreen = true
              $('.step-main-mirror').width(
                ($(window).width() / self.iframeHeight) * self.iframeHeight
              )
              setTimeout(() => {
                // $('.mirror-iframe').width($(".step-main-mirror").width() - 1)
                $('.mirror-iframe').width($('.step-main-mirror').width() - 48)
                $('.mirror-iframe').css('margin-left', '20px')
                $('.iframs').css('margin-left', '25px')
              }, 1000)
            } else {
              setTimeout(() => {
                self.iframeHeight = $(window).height() - 60
                $('.mirror-iframe, .step-main-mirror').width(
                  (1024 / 768) * ($(window).height() - 60)
                )
                $('.jx-virtual-machine-main').height(self.iframeHeight)
                $('.step-main-content').width(
                  $(window).width() - $('.step-main-mirror').width()
                )
              }, 800)
            }
            setTimeout(() => {
              // 虚机地址默认设置主节点
              self.VirtualMachineUrl =
                res.data[index].desktopUrl || res.data[index].notebookUrl

              // 虚机地址数组
              self.VirtualMachineUrlArr = res.data
              self.deskLoading = false
              if (self.ScreenSigma < 1.44) {
                self
                  .$confirm(
                    '系统检测到您的系统分辨率太小，是否切换到全屏模式？',
                    '提示',
                    {
                      confirmButtonText: '确定',
                      cancelButtonText: '取消',
                      type: 'warning',
                      closeOnClickModal: false,
                    }
                  )
                  .then(() => {
                    self.VirtualFullScreen(2)
                  })
              }
            }, 800)
          } else {
            // self.deskLoading = false
            // self.$message.error(res.message)
            // 错误提示
            self.mirrorIframeTip = true
            self.mirrorIframeTipText = res.message
            self.deskLoading = false
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 虚机导航列表切换
    MachineNavTab2(index, item) {
      let self = this
      self.MachineNavTabIndex = index

      self.VirtualMachineId = item.containerId

      self.VirtualImageId = item.imageId
      // 重新初始化进入实验
      // self.InitExperiment(index)
    },
    // 刷新虚机
    refreshVirtual(index) {
      let self = this
      self.MachineNavTabIndex = index
      // 关闭手册拖拽弹窗
      self.dialogHandbookDrag1 = false
      self.dialogHandbookDrag2 = false
      // 重新初始化进入实验
      // self.InitExperiment(index)
      self.deskLoading = true
      self.deskLoadingText = '桌面加載中'
      self.VirtualMachineUrl = ''

      self.VirtualMachineUrlArr = []
      // 清空虚机切换列表导航集合
      self.VirtualMachineIdArr = []
      self.virtualMachineNavList = []
      self.$http
        .get('/tes/image-allocation/course/' + self.taskId + '/experiment')
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            self.mirrorIframeTip = false
            if (
              res.data[0].fullScreen ||
              (res.data[0].notebook && self.fullScreen)
            ) {
              self.fullScreen = true
              // 把距离加上
              $('.mirror-iframe').css('margin-left', '45px')
            }
            // 初始化虚拟机信息
            self.VirtualMachineInfo = res.data
            // 虚机地址默认设置主节点
            self.VirtualMachineUrl =
              res.data[index].desktopUrl || res.data[index].notebookUrl

            // 虚机地址数组
            self.VirtualMachineUrlArr = res.data
            // 虚机容器ID
            self.VirtualMachineId = res.data[index].containerId
            // 虚机镜像id
            self.VirtualImageId = res.data[index].imageId

            let fullData = []
            for (let i = 0; i < res.data.length; i++) {
              self.VirtualMachineIdArr.push(res.data[i].containerId)
              // 虚机切换列表导航集合
              self.virtualMachineNavList.push(res.data[i].containerRole)
              // 如果含有全屏状态
              // if(res.data[i].fullScreen){
              //     fullData.push(res.data[i].containerId)
              //     self.VirtualFullScreen(1,fullData)
              // }
              fullData.push(res.data[i].containerId)
            }
            if (!res.data[0].fullScreen && !res.data[0].notebook) {
              self.fullScreen = false
              setTimeout(() => {
                self.iframeHeight = $(window).height() - 60
                $('.mirror-iframe, .step-main-mirror').width(
                  (1024 / 768) * ($(window).height() - 60)
                )
                $('.jx-virtual-machine-main').height(self.iframeHeight)
                $('.step-main-content').width(
                  $(window).width() - $('.step-main-mirror').width()
                )
                // 把距离去掉
                $('.mirror-iframe').css('margin-left', '0')
                $('.iframs').css('margin-left', '0')
              }, 800)
            }
            if (res.data[0] && res.data[0].notebook) {
              if (self.fullScreen) {
                $('.step-main-mirror').width(
                  ($(window).width() / self.iframeHeight) * self.iframeHeight
                )
                setTimeout(() => {
                  // $('.mirror-iframe').width($(".step-main-mirror").width() - 1)
                  $('.mirror-iframe').width($('.step-main-mirror').width() - 48)
                  $('.mirror-iframe').css('margin-left', '20px')
                  $('.iframs').css('margin-left', '25px')
                }, 1000)
              } else {
                setTimeout(() => {
                  self.iframeHeight = $(window).height() - 60
                  $('.mirror-iframe, .step-main-mirror').width(
                    (1024 / 768) * ($(window).height() - 60)
                  )
                  $('.jx-virtual-machine-main').height(self.iframeHeight)
                  $('.step-main-content').width(
                    $(window).width() - $('.step-main-mirror').width()
                  )
                  // 把距离去掉
                  $('.mirror-iframe').css('margin-left', '0')
                  $('.iframs').css('margin-left', '0')
                }, 1000)
              }
            }
            self.deskLoading = false
            this.$nextTick(function () {
              const iframe =
                window.frames['VirtualMachineIframe' + self.VirtualMachineId]
              const handleLoad = () => {
                setTimeout(() => {
                  // const dom = (iframe.contentWindow || iframe.contentDocument)
                  const iframeDoc = iframe.contentDocument
                    ? iframe.contentDocument
                    : iframe.contentWindow.document
                  // console.log(iframeDoc)
                  const menu =
                    iframeDoc.getElementsByClassName('jp-DirListing-item')[1]
                  // console.log(menu)
                  menu.addEventListener('click', function (e) {}, false)
                  var evt = iframeDoc.createEvent('MouseEvents')
                  evt.initEvent('click', true, true)
                  // console.log(evt)
                  menu.dispatchEvent(evt)
                }, 5000)
              }
              iframe.addEventListener('load', handleLoad, true)
              // console.log('jp-DirListing-item');
              // console.log($('.jp-DirListing-item'))
              // console.log($('jx-modify-virtual-machine'))
              // console.log($('.jp-DirListing-item').html())
            }, 3000)
          } else {
            self.mirrorIframeTip = true
            self.mirrorIframeTipText = res.message
            self.deskLoading = false
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },

    // 初始化虚机
    InitVirtual(index) {
      let self = this
      self.dialogInitVirtual = true
    },
    DialogInitVirtualSave(index) {
      let self = this
      // 关闭手册拖拽弹窗
      self.dialogHandbookDrag1 = false
      self.dialogHandbookDrag2 = false
      self.MachineNavTabIndex = 0
      self.VirtualMachineUrl = ''
      self.VirtualMachineUrlArr = []
      self.VirtualMachineIdArr = []
      self.virtualMachineNavList = []
      self.fullScreen = false

      self.dialogInitVirtual = false
      self.deskLoading = true
      self.deskLoadingText = '初始化中'
      self.$http
        .get('/tes/image-allocation/course/' + self.taskId + '/experiment/init')
        .then((response) => {
          let res = response.data

          if (res.code == '200') {
            // 初始化虚拟机信息
            self.VirtualMachineInfo = res.data
            self.mirrorIframeTip = false
            // setTimeout(() => {
            //     self.iframeHeight = $(window).height() - 60
            //     $(".mirror-iframe, .step-main-mirror").width($(window).width() - $('.step-main-content').width())
            //     $('.jx-virtual-machine-main').height(self.iframeHeight)
            //     $(".step-main-content").width($(window).width() - $(".step-main-mirror").width())
            //     //把距离去掉
            //     $('.mirror-iframe').css('margin-left','0')
            //     $('.iframs').css('margin-left','0')
            // }, 800);
            // self.deskLoading = false

            // 虚机ID
            self.VirtualMachineId = res.data[index].containerId

            // 镜像ID初始化
            self.VirtualImageId = res.data[index].imageId
            let fullData = []
            for (let i = 0; i < res.data.length; i++) {
              self.VirtualMachineIdArr.push(res.data[i].containerId)
              // 虚机切换列表导航集合
              self.virtualMachineNavList.push(res.data[i].containerRole)
              // 如果含有全屏状态
              if (res.data[i].fullScreen && !res.data[i].notebook) {
                fullData.push(res.data[i].containerId)
                self.VirtualFullScreen(1, fullData)
              }
            }
            if (res.data[0] && res.data[0].notebook) {
              self.fullScreen = true
              $('.step-main-mirror').width(
                ($(window).width() / self.iframeHeight) * self.iframeHeight
              )
              setTimeout(() => {
                // $('.mirror-iframe').width($(".step-main-mirror").width() - 1)
                $('.mirror-iframe').width($('.step-main-mirror').width() - 48)
                $('.mirror-iframe').css('margin-left', '20px')
                $('.iframs').css('margin-left', '25px')
              }, 1000)
            } else {
              setTimeout(() => {
                self.iframeHeight = $(window).height() - 60
                $('.mirror-iframe, .step-main-mirror').width(
                  $(window).width() - $('.step-main-content').width()
                )
                $('.jx-virtual-machine-main').height(self.iframeHeight)
                $('.step-main-content').width(
                  $(window).width() - $('.step-main-mirror').width()
                )
                // 把距离去掉
                $('.mirror-iframe').css('margin-left', '0')
                $('.iframs').css('margin-left', '0')
              }, 800)
            }
            // self.$message({
            //     type: 'success',
            //     message: '初始化成功!'
            // })
            // if(self.ScreenSigma < 1.44){
            //     self.$confirm('系统检测到您的系统分辨率太小，是否切换到全屏模式？', '提示', {
            //         confirmButtonText: '确定',
            //         cancelButtonText: '取消',
            //         type: 'warning',
            //         closeOnClickModal: false
            //     }).then(() => {
            //         self.VirtualFullScreen(2)
            //     })
            // }
            setTimeout(() => {
              // 虚机地址默认设置主节点
              self.VirtualMachineUrl =
                res.data[index].desktopUrl || res.data[index].notebookUrl

              // 虚机地址数组
              self.VirtualMachineUrlArr = res.data
              self.deskLoading = false
              self.$message({
                type: 'success',
                message: '初始化成功!',
              })
              if (self.ScreenSigma < 1.44) {
                self
                  .$confirm(
                    '系统检测到您的系统分辨率太小，是否切换到全屏模式？',
                    '提示',
                    {
                      confirmButtonText: '确定',
                      cancelButtonText: '取消',
                      type: 'warning',
                      closeOnClickModal: false,
                    }
                  )
                  .then(() => {
                    self.VirtualFullScreen(2)
                  })
              }
            }, 5000)
          } else {
            setTimeout(() => {
              self.iframeHeight = $(window).height() - 60
              $('.mirror-iframe, .step-main-mirror').width(
                $(window).width() - $('.step-main-content').width()
              )
              $('.jx-virtual-machine-main').height(self.iframeHeight)
              $('.step-main-content').width(
                $(window).width() - $('.step-main-mirror').width()
              )
            }, 800)
            self.mirrorIframeTip = true
            self.mirrorIframeTipText = res.message
            self.deskLoading = false
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 全屏，退出全屏
    VirtualFullScreen(index, fullData) {
      let self = this
      const loading = self.$loading({
        lock: true,
        text: '虚机切换中',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      let data = {}
      if (index == 1) {
        data = {
          containerIds: fullData,
          length: '1024',
          width: '768',
          fullScreen: false,
          contextId: self.taskId,
        }
      } else if (index == 2) {
        data = {
          containerIds: self.VirtualMachineIdArr,
          length: window.screen.availWidth - 60,
          width: self.iframeHeight,
          fullScreen: true,
          contextId: self.taskId,
        }
      } else if (index == 3) {
        this.getTaskAndAnwser()
        // 退出全屏
        // 关闭手册拖拽弹窗
        self.dialogHandbookDrag1 = false
        self.dialogHandbookDrag2 = false
        data = {
          containerIds: self.VirtualMachineIdArr,
          length: '1024',
          width: '768',
          fullScreen: false,
          contextId: self.taskId,
        }
      }
      self.$http
        .post('/tes/experiment/container/display', data)
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            // 关闭loading
            loading.close()
            if (index == 2) {
              self.fullScreen = true
              $('.step-main-mirror').width(
                ($(window).width() / self.iframeHeight) * self.iframeHeight
              )
              setTimeout(() => {
                // $('.mirror-iframe').width($(".step-main-mirror").width() - 1)
                $('.mirror-iframe').width($('.step-main-mirror').width() - 48)
                $('.mirror-iframe').css('margin-left', '20px')
                $('.iframs').css('margin-left', '25px')
              }, 1000)
            } else if (index == 3 || index == 1) {
              if (self.stepTypeStr != '多步骤实验') {
                self.getTaskAndAnwser()
              } else {
                self.getTaskAndAnwser()
                self.getTaskAndAnwser(self.stepChapterId)
              }
              self.fullScreen = false
              setTimeout(() => {
                self.iframeHeight = $(window).height() - 60
                $('.mirror-iframe, .step-main-mirror').width(
                  (1024 / 768) * ($(window).height() - 60)
                )
                $('.jx-virtual-machine-main').height(self.iframeHeight)
                $('.step-main-content').width(
                  $(window).width() - $('.step-main-mirror').width()
                )
                $('.mirror-iframe').css('margin-left', '0')
                $('.iframs').css('margin-left', '0')
              }, 1000)
            }
          } else {
            // 关闭loading
            loading.close()
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 图标切换
    IconChange(id) {
      let self = this
      self.MirrorForm.iconId = id
    },
    // 镜像保存radio切换
    MirrorRadioChange() {
      let self = this
      if (self.MirrorForm.saveWay == 1) {
        self.$http
          .get('/tes/image-allocation/image/' + self.VirtualImageId)
          .then((response) => {
            let res = response.data
            if (res.code == '200') {
              let iconIdIndex
              self.MirrorForm.MirrorName = res.data.imageName
              self.MirrorForm.MirrorNameNum =
                50 - self.MirrorForm.MirrorName.length
              self.MirrorForm.iconId = res.data.icon
              iconIdIndex = self.indexOfFn(
                self.iconListData,
                self.MirrorForm.iconId
              )
              self.MirrorForm.MirrorDesc = res.data.description
              self.MirrorForm.MirrorDescNum =
                200 - self.MirrorForm.MirrorDesc.length
              self.swiperDialogOption = {
                slidesPerView: 5,
                spaceBetween: 24,
                initialSlide: iconIdIndex,
                loop: false,
                navigation: {
                  nextEl: '.swiper-button-next',
                  prevEl: '.swiper-button-prev',
                },
              }
            } else {
              self.$message.error(res.message)
            }
          })
          .catch((err) => {
            console.log(err)
          })
      } else {
        self.MirrorForm.MirrorName = ''
        self.MirrorForm.MirrorNameNum = 50
        self.MirrorForm.iconId = ''
        self.MirrorForm.MirrorDesc = ''
        self.MirrorForm.MirrorDescNum = 200
        self.swiperDialogOption.initialSlide = 1
      }
    },
    // 镜像保存弹窗
    VirtualSave() {
      let self = this
      self.MirrorForm.MirrorName = ''
      self.MirrorForm.MirrorNameNum = 50
      self.MirrorForm.iconId = ''
      self.MirrorForm.MirrorDesc = ''
      self.MirrorForm.MirrorDescNum = 200
      self.swiperDialogOption.initialSlide = 1
      self.iconListData = ''
      self.$http
        .get('/tes/image/icon')
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            self.iconListData = res.data
          } else {
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
      self.$http
        .get('/tes/image-allocation/image/' + self.VirtualImageId + '/self')
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            // 保存镜像方式radio状态赋值
            self.saveWayStatus = !!res.data
            // 二期新增需求 gpu提示
            self.gpuFn()
            // 判断保存或创建
            if (res.data) {
              // 镜像保存信息
              self.VirtualInfo()
            } else {
              self.dialogMirrorInfo = true
            }
          } else {
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    gpuFn() {
      let self = this
      self.$http
        .get('/tes/image-allocation/image/' + self.VirtualImageId)
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            self.gpuStatus = res.data.gpu
            self.notebookStatus = res.data.notebook
          } else {
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    VirtualInfo() {
      let self = this
      self.$http
        .get('/tes/image-allocation/image/' + self.VirtualImageId)
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            let iconIdIndex
            self.MirrorForm.MirrorName = res.data.imageName
            self.MirrorForm.MirrorNameNum =
              50 - self.MirrorForm.MirrorName.length
            self.MirrorForm.iconId = res.data.icon
            iconIdIndex = self.indexOfFn(
              self.iconListData,
              self.MirrorForm.iconId
            )
            self.MirrorForm.MirrorDesc = res.data.description
            self.MirrorForm.MirrorDescNum =
              200 - self.MirrorForm.MirrorDesc.length
            self.swiperDialogOption = {
              slidesPerView: 5,
              spaceBetween: 24,
              initialSlide: iconIdIndex,
              loop: false,
              navigation: {
                nextEl: '.swiper-button-next',
                prevEl: '.swiper-button-prev',
              },
            }
            self.dialogMirrorInfo = true
          } else {
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    indexOfFn(arr, item) {
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].icon == item) {
          return i
        }
      }
    },
    // 镜像名称
    MirrorNameInput() {
      let self = this
      let MirrorTextLength = self.MirrorForm.MirrorName.length
      self.MirrorForm.MirrorNameNum = 50 - MirrorTextLength
    },
    // 镜像简介
    MirrorDescInput() {
      let self = this
      let MirrorTextLength = self.MirrorForm.MirrorDesc.length
      self.MirrorForm.MirrorDescNum = 200 - MirrorTextLength
    },
    // 保存镜像保存
    MirrorFormSave(form) {
      let self = this
      if (self.MirrorForm.saveWay == 1) {
        self.$refs[form].validate((valid) => {
          if (valid) {
            self.$http
              .put('/tes/image-allocation/image' + self.VirtualImageId, {
                containerId: self.VirtualMachineId,
                imageName: self.MirrorForm.MirrorName,
                icon: self.MirrorForm.iconId,
                description: self.MirrorForm.MirrorDesc,
              })
              .then((response) => {
                let res = response.data
                if (res.code == '200') {
                  // 重新赋值镜像ID

                  self.VirtualImageId = res.data
                  // 重新配置镜像
                  self.singleVirtual()
                } else {
                  self.$message.error(res.message)
                }
              })
              .catch((err) => {
                console.log(err)
              })
          }
        })
      } else {
        self.$refs[form].validate((valid) => {
          if (valid) {
            self.$http
              .post('/tes/image-allocation/image', {
                containerId: self.VirtualMachineId,
                imageName: self.MirrorForm.MirrorName,
                icon: self.MirrorForm.iconId,
                description: self.MirrorForm.MirrorDesc,
              })
              .then((response) => {
                let res = response.data
                if (res.code == '200') {
                  // 重新赋值镜像ID
                  self.VirtualImageId = res.data

                  // 重新配置镜像
                  self.singleVirtual()
                } else {
                  self.$message.error(res.message)
                }
              })
              .catch((err) => {
                console.log(err)
              })
          }
        })
      }
    },
    // 重新配置镜像
    singleVirtual() {
      let self = this

      self.$http
        .put('/tes/image-allocation/course/' + self.taskId, {
          imageId: self.VirtualImageId,
          containerId: self.VirtualMachineId,
        })
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            self.dialogMirrorInfo = false
          } else {
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 修改镜像保存
    ModifyMirrorFormSave(form) {
      let self = this
      self.$refs[form].validate((valid) => {
        if (valid) {
          if (self.MirrorForm.iconId == '') {
            self.$message.error('请选择镜像图标')
            return
          }
          if (!self.saveWayStatus) {
            self.CreatedMirrorForm()
            return
          }
          // 镜像保存更新
          if (self.MirrorForm.saveWay == 1) {
            self.contentLoading = self.$loading({
              lock: true,
              text: '镜像保存中',
              spinner: 'el-icon-loading',
              background: 'rgba(0, 0, 0, 0.7)',
            })
            self.$http
              .put('/tes/image-allocation/image/' + self.VirtualImageId, {
                containerId: self.VirtualMachineId,
                imageName: self.MirrorForm.MirrorName,
                icon: self.MirrorForm.iconId,
                description: self.MirrorForm.MirrorDesc,
              })
              .then((response) => {
                let res = response.data
                if (res.code == '200') {
                  self.$message({
                    message: '保存成功',
                    type: 'success',
                  })

                  self.contentLoading.close()
                  self.dialogMirrorInfo = false
                } else {
                  self.contentLoading.close()
                  self.dialogMirrorInfo = false
                  self.$message.error(res.message)
                }
              })
              .catch((err) => {
                console.log(err)
              })
          } else {
            // 镜像保存创建
            self.CreatedMirrorForm()
          }
        }
      })
    },
    // 镜像保存创建
    CreatedMirrorForm() {
      let self = this
      self.contentLoading = self.$loading({
        lock: true,
        text: '镜像创建中',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      self.$http
        .post('/tes/image-allocation/image', {
          containerId: self.VirtualMachineId,
          imageName: self.MirrorForm.MirrorName,
          icon: self.MirrorForm.iconId,
          description: self.MirrorForm.MirrorDesc,
        })
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            self.$message({
              message: '保存成功',
              type: 'success',
            })
            for (let i = 0; i < self.VirtualMachineUrlArr.length; i++) {
              if (self.VirtualMachineUrlArr[i].imageId == self.VirtualImageId) {
                self.VirtualMachineUrlArr[i].imageId = res.data
              }
            }
            self.VirtualImageId = res.data
            self.singleVirtual()
            self.contentLoading.close()
            self.dialogMirrorInfo = false
          } else {
            self.contentLoading.close()
            self.dialogMirrorInfo = false
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 查询NoteBook镜像列表
    getImageList(is_notebook) {
      this.$http
        .get(
          '/tes/image-allocation/image?cluster=false&notebook=' + is_notebook
        )
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            this.distributionform.options0 = res.data
          } else {
            this.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 选择实验类型
    experimentTypeChange(e) {
      this.distributionform.resource = 1
      this.distributionform.distributedData.cpuValue = ''
      this.distributionform.distributedData.ramValue = ''
      // this.distributionform.distributedData.switchValue = false
      this.distributionform.mirrorConfigData.cpuValue = ''
      this.distributionform.mirrorConfigData.ramValue = ''
      this.distributionform.mirrorConfigData.switchValue = false
      this.distributionform.nodeMianData.cpuValue = ''
      this.distributionform.nodeMianData.ramValue = ''
      this.distributionform.optionsValue0 = []
      this.distributionform.optionsValue1 = []
      this.distributionform.optionsValue2 = []
      this.distributionform.optionsValue3 = []
      this.distributionform.optionsValue4 = []
      this.distributionform.optionsValue5 = []
      this.distributionform.optionsValue6 = []
      this.distributionform.optionsValue7 = []
      this.distributionform.virtualStepCurrent = 1
      this.distributionform.distributionData = ''
      let type = e != 1
      this.getImageList(type)
    },
    // 跳转到编辑实验镜像页
    VirtualLink() {
      let self = this
      // self.distributionform.resource = 1
      // let cluster = self.distributionform.resource == 1 ? false : true

      self.getImageList(false)
      self.$http
        .get('/tes/image-allocation/image?cluster=true&notebook=false')
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            self.distributionform.options1 = res.data
            self.distributionform.options2 = res.data
            self.distributionform.options3 = res.data
            self.distributionform.options4 = res.data
            self.distributionform.options5 = res.data
            self.distributionform.options6 = res.data
            self.distributionform.options7 = res.data
          } else {
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
      // 显示分配镜像弹窗
      self.dialogDistributionFormVisible = true
      self.$http
        .get(
          '/tes/image-allocation/course/' + self.courseId + '/' + self.taskId
        )
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            if (res.data.allocated) {
              self.distributionform.experimentType = res.data.type
              // 获取可视化实验单节点/notebook实验镜像列表
              if (res.data.type == 2) {
                self.getImageList(true)
              }
              if (res.data.mode == 1) {
                self.distributionform.resource = res.data.mode
                // 伪分布取值
                self.distributionform.distributedData.cpuValue =
                  '' + res.data.cpu + ''
                self.distributionform.distributedData.ramValue =
                  '' + res.data.ram + ''
                // self.distributionform.distributedData.switchValue = res.data.gpu

                self.distributionform.optionsValue0 = [
                  res.data.image.imageSource,
                  res.data.image.imageId,
                ]
                self.handleItemChange(self.distributionform.optionsValue0)
              } else if (res.data.mode == 2) {
                self.distributionform.resource = res.data.mode
                // 主节点取值
                self.distributionform.nodeMianData.cpuValue =
                  '' + res.data.cpu + ''
                self.distributionform.nodeMianData.ramValue =
                  '' + res.data.ram + ''
                self.distributionform.nodeMianData.switchValue = res.data.gpu

                self.distributionform.optionsValue7 = [
                  res.data.image.imageSource,
                  res.data.image.imageId,
                ]
                // 从节点镜像配置
                self.distributionform.mirrorConfigData.cpuValue =
                  '' + res.data.slaveCpu + ''
                self.distributionform.mirrorConfigData.ramValue =
                  '' + res.data.slaveRam + ''
                self.distributionform.mirrorConfigData.switchValue =
                  res.data.slaveGpu
                self.distributionform.virtualStepCurrent = res.data.slaveSize
                self.$nextTick(() => {
                  if (res.data.slaveSize == 1) {
                    self.distributionform.optionsValue1 = [
                      res.data.slaveImages[0].imageSource,
                      res.data.slaveImages[0].imageId,
                    ]
                  } else if (res.data.slaveSize == 2) {
                    self.distributionform.optionsValue1 = [
                      res.data.slaveImages[0].imageSource,
                      res.data.slaveImages[0].imageId,
                    ]
                    self.distributionform.optionsValue2 = [
                      res.data.slaveImages[1].imageSource,
                      res.data.slaveImages[1].imageId,
                    ]
                  } else if (res.data.slaveSize == 4) {
                    self.distributionform.optionsValue1 = [
                      res.data.slaveImages[0].imageSource,
                      res.data.slaveImages[0].imageId,
                    ]
                    self.distributionform.optionsValue2 = [
                      res.data.slaveImages[1].imageSource,
                      res.data.slaveImages[1].imageId,
                    ]
                    self.distributionform.optionsValue3 = [
                      res.data.slaveImages[2].imageSource,
                      res.data.slaveImages[2].imageId,
                    ]
                    self.distributionform.optionsValue4 = [
                      res.data.slaveImages[3].imageSource,
                      res.data.slaveImages[3].imageId,
                    ]
                  } else if (res.data.slaveSize == 6) {
                    self.distributionform.optionsValue1 = [
                      res.data.slaveImages[0].imageSource,
                      res.data.slaveImages[0].imageId,
                    ]
                    self.distributionform.optionsValue2 = [
                      res.data.slaveImages[1].imageSource,
                      res.data.slaveImages[1].imageId,
                    ]
                    self.distributionform.optionsValue3 = [
                      res.data.slaveImages[2].imageSource,
                      res.data.slaveImages[2].imageId,
                    ]
                    self.distributionform.optionsValue4 = [
                      res.data.slaveImages[3].imageSource,
                      res.data.slaveImages[3].imageId,
                    ]
                    self.distributionform.optionsValue5 = [
                      res.data.slaveImages[4].imageSource,
                      res.data.slaveImages[4].imageId,
                    ]
                    self.distributionform.optionsValue6 = [
                      res.data.slaveImages[5].imageSource,
                      res.data.slaveImages[5].imageId,
                    ]
                  }
                })
                self.handleItemChange(self.distributionform.optionsValue7)
              }
            }
          } else {
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 弹窗step切换
    AddClass(index) {
      let self = this
      // if(index != 2){
      //     return
      // }
      self.distributionform.virtualStepCurrent = index
    },
    // 分配镜像
    // 表单提交
    DistributionFormSave(formName, tag) {
      // tag标记1.保存 2.保存并跳转实验镜像
      let self = this
      self.$refs[formName].validate((valid) => {
        if (valid) {
          let data = {},
            slaveImageIdsArr = []
          // data.chapterIds = self.chapterId
          data.mode = self.distributionform.resource
          data.experimentType = self.distributionform.experimentType
          if (self.distributionform.resource == 1) {
            data.imageId = self.distributionform.optionsValue0[1]
              ? self.distributionform.optionsValue0[1]
              : ''
            data.cpu = self.distributionform.distributedData.cpuValue
            data.ram = self.distributionform.distributedData.ramValue
            // data.gpu = self.distributionform.distributedData.switchValue

            if (data.imageId == '') {
              self.$message.error('请选择镜像')
              return
            }
          } else if (self.distributionform.resource == 2) {
            data.imageId = self.distributionform.optionsValue7[1]
              ? self.distributionform.optionsValue7[1]
              : ''
            data.cpu = self.distributionform.nodeMianData.cpuValue
            data.ram = self.distributionform.nodeMianData.ramValue
            data.gpu = self.distributionform.nodeMianData.switchValue
            data.slaveCpu = self.distributionform.mirrorConfigData.cpuValue
            data.slaveRam = self.distributionform.mirrorConfigData.ramValue
            data.slaveGpu = self.distributionform.mirrorConfigData.switchValue

            if (data.imageId == '') {
              self.$message.error('请选择主节点镜像')
              return
            }

            if (self.distributionform.virtualStepCurrent == 1) {
              slaveImageIdsArr.push(self.distributionform.optionsValue1[1])
              if (self.distributionform.optionsValue1[1] == undefined) {
                self.$message.error('请选择从节点1镜像')
                return
              }
            } else if (self.distributionform.virtualStepCurrent == 2) {
              slaveImageIdsArr.push(self.distributionform.optionsValue1[1])
              if (self.distributionform.optionsValue1[1] == undefined) {
                self.$message.error('请选择从节点1镜像')
                return
              }
              slaveImageIdsArr.push(self.distributionform.optionsValue2[1])
              if (self.distributionform.optionsValue2[1] == undefined) {
                self.$message.error('请选择从节点2镜像')
                return
              }
            } else if (self.distributionform.virtualStepCurrent == 4) {
              slaveImageIdsArr.push(self.distributionform.optionsValue1[1])
              if (self.distributionform.optionsValue1[1] == undefined) {
                self.$message.error('请选择从节点1镜像')
                return
              }
              slaveImageIdsArr.push(self.distributionform.optionsValue2[1])
              if (self.distributionform.optionsValue2[1] == undefined) {
                self.$message.error('请选择从节点2镜像')
                return
              }
              slaveImageIdsArr.push(self.distributionform.optionsValue3[1])
              if (self.distributionform.optionsValue3[1] == undefined) {
                self.$message.error('请选择从节点3镜像')
                return
              }
              slaveImageIdsArr.push(self.distributionform.optionsValue4[1])
              if (self.distributionform.optionsValue4[1] == undefined) {
                self.$message.error('请选择从节点4镜像')
                return
              }
            } else if (self.distributionform.virtualStepCurrent == 6) {
              slaveImageIdsArr.push(self.distributionform.optionsValue1[1])
              if (self.distributionform.optionsValue1[1] == undefined) {
                self.$message.error('请选择从节点1镜像')
                return
              }
              slaveImageIdsArr.push(self.distributionform.optionsValue2[1])
              if (self.distributionform.optionsValue2[1] == undefined) {
                self.$message.error('请选择从节点2镜像')
                return
              }
              slaveImageIdsArr.push(self.distributionform.optionsValue3[1])
              if (self.distributionform.optionsValue3[1] == undefined) {
                self.$message.error('请选择从节点3镜像')
                return
              }
              slaveImageIdsArr.push(self.distributionform.optionsValue4[1])
              if (self.distributionform.optionsValue4[1] == undefined) {
                self.$message.error('请选择从节点4镜像')
                return
              }
              slaveImageIdsArr.push(self.distributionform.optionsValue5[1])
              if (self.distributionform.optionsValue5[1] == undefined) {
                self.$message.error('请选择从节点5镜像')
                return
              }
              slaveImageIdsArr.push(self.distributionform.optionsValue6[1])
              if (self.distributionform.optionsValue6[1] == undefined) {
                self.$message.error('请选择从节点6镜像')
                return
              }
            }
            data.slaveImageIds = slaveImageIdsArr
          }
          self.$http
            .post('/tes/image-allocation/course/' + self.taskId, data)
            .then((response) => {
              let res = response.data
              if (res.code == '200') {
                // 镜像分配弹窗隐藏
                self.dialogDistributionFormVisible = false

                // 配置成功调用刷新方式
                // self.InitConfigVirtual(0)
                self.refreshVirtual(0)
              } else {
                self.$message.error(res.message)
              }
            })
            .catch((err) => {
              console.log(err)
            })
        }
      })
    },
    InitConfigVirtual(index) {
      let self = this

      self.MachineNavTabIndex = 0
      self.VirtualMachineUrl = ''
      // 虚机地址数组
      self.VirtualMachineUrlArr = []
      self.VirtualMachineIdArr = []
      self.virtualMachineNavList = []

      self.fullScreen = false
      self.deskLoading = true
      self.deskLoadingText = '重选配置中'
      self.$http
        .get('/tes/image-allocation/course/' + self.taskId + '/experiment/init')
        .then((response) => {
          let res = response.data

          if (res.code == '200') {
            self.mirrorIframeTip = false
            // 初始化虚拟机信息
            self.VirtualMachineInfo = res.data

            setTimeout(() => {
              self.iframeHeight = $(window).height() - 60
              $('.mirror-iframe, .step-main-mirror').width(
                (1024 / 768) * ($(window).height() - 60)
              )
              $('.jx-virtual-machine-main').height(self.iframeHeight)
              $('.step-main-content').width(
                $(window).width() - $('.step-main-mirror').width()
              )
            }, 800)
            self.deskLoading = false

            // 虚机地址默认设置主节点
            self.VirtualMachineUrl = res.data[index].desktopUrl
            // 虚机地址数组
            self.VirtualMachineUrlArr = res.data
            // 虚机ID
            self.VirtualMachineId = res.data[index].containerId

            // 镜像ID初始化
            self.VirtualImageId = res.data[index].imageId
            let fullData = []
            for (let i = 0; i < res.data.length; i++) {
              self.VirtualMachineIdArr.push(res.data[i].containerId)
              // 虚机切换列表导航集合
              self.virtualMachineNavList.push(res.data[i].containerRole)
              // 如果含有全屏状态
              if (res.data[i].fullScreen) {
                fullData.push(res.data[i].containerId)
                self.VirtualFullScreen(1, fullData)
              }
            }
            self.$message({
              message: '重选配置成功',
              type: 'success',
            })
          } else {
            self.mirrorIframeTip = true
            self.mirrorIframeTipText = res.message
            self.deskLoading = false
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    handleItemChange(data) {
      let self = this
      if (data[1]) {
        self.$http
          .get('/tes/image-allocation/image/' + data[1])
          .then((response) => {
            let res = response.data
            if (res.code == '200') {
              self.distributionform.distributionData = res.data
            } else {
              self.$message.error(res.message)
            }
          })
          .catch((err) => {
            console.log(err)
          })
      }
    },
    // stfp工具
    SftpConfig() {
      let self = this
      self.$http
        .get('/tes/experiment/container/' + self.VirtualMachineId + '/ftp')
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            let sftpArr = res.data.split('@')
            self.sftpIp = sftpArr
            self.sftpPort = self.sftpIp[0].split(':')
            self.dialogSftp = true
          } else {
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },
    // 剪贴板字符限制
    CutContentInput() {
      let self = this
      let MirrorTextLength = self.cutData.cutRuleForm.desc.length
      self.cutData.cutRuleForm.descNum = 20000 - MirrorTextLength
    },
    // 剪切板弹窗
    CutDialog() {
      let self = this
      self.dialogCut = true
      self.cutData.cutRuleForm.descNum = 20000
      self.cutData.cutRuleForm.desc = ''
    },
    CutCloseDialog() {
      let self = this
      self.$refs['cutRuleForm'].resetFields()
    },
    // 剪切板表单提交
    cutSubmitForm(formName) {
      let self = this
      self.$refs[formName].validate((valid) => {
        if (valid) {
          const loading = self.$loading({
            lock: true,
            text: '剪切文件提交中',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)',
          })
          self.$http
            .post(
              '/tes/experiment/container/' +
                self.VirtualMachineId +
                '/clipboard',
              {
                content: self.cutData.cutRuleForm.desc,
                contextId: self.taskId,
              }
            )
            .then((response) => {
              let res = response.data
              if (res.code == '200') {
                loading.close()
                self.$message({
                  type: 'success',
                  message: '保存成功!',
                })
                self.dialogCut = false
              } else {
                loading.close()
                self.$message.error(res.message)
              }
            })
            .catch((err) => {
              console.log(err)
            })
        }
      })
    },
    // 文件上传弹窗显示
    UploadFile() {
      let self = this
      self.FileUploadForm.fileName = ''
      self.FileUploadForm.versionFile = ''
      self.dialogFileUpload = true
      $('#version-file-upload').val('')
    },
    // 文件上传清除上传提示文本
    CloseFileUploadDialog() {
      let self = this
      self.FileUploadForm.fileName = ''
      $('#version-file-upload').val('')
    },
    // 上传文件
    getFile($event) {
      let self = this
      let isLt2M = $event.target.files[0].size / 1024 / 1024 < 500
      let fileType = $event.target.files[0].name
      fileType = fileType.substring(
        fileType.lastIndexOf('.') + 1,
        fileType.length
      )
      if (!isLt2M) {
        self.$message.error('上传文件大小不能超过 500MB!')
        return false
      }
      self.FileUploadForm.fileName = $event.target.files[0]
      self.FileUploadForm.versionFile = $event.target.files[0].name
    },
    // 保存上传文件
    UploadSave(form) {
      let self = this
      if (self.FileUploadForm.fileName == '') {
        self.$message.error('请上传文件')
        return
      }
      self.contentLoading = self.$loading({
        lock: true,
        text: '文件上传中',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      let formData = new FormData()
      formData.append('file', self.FileUploadForm.fileName)
      self.$http
        .post(
          '/tes/experiment/container/' + self.VirtualMachineId + '/upload',
          formData,
          { headers: { 'Content-Type': 'multipart/form-data' } }
        )
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            self.$message({
              message: '上传成功',
              type: 'success',
            })
            self.dialogFileUpload = false
            self.contentLoading.close()
            self.$refs[form].resetFields()
          } else {
            self.contentLoading.close()
            self.$message.error(res.message)
          }
        })
        .catch((err) => {
          console.log(err)
        })
    },

    // 实验截图
    ExperimentScreenshot() {
      let self = this
      var vir = document.getElementById(
        'VirtualMachineIframe' + self.VirtualMachineId
      )
      self.dialogScreenshotUrl = self
        .convertCanvasToImage(
          vir.contentWindow.document.getElementsByTagName('canvas')[0]
        )
        .getAttribute('src')

      self.$http
        .post('/tes/base64/file-save', {
          base64Info: self.dialogScreenshotUrl,
        })
        .then((response) => {
          let res = response.data
          if (res.code == '200') {
            self.dialogScreenshotCopyUrl = res.data
            self.dialogScreenshot = true
          }
        })
    },
    convertCanvasToImage(canvas) {
      let image = new Image()
      image.crossOrigin = 'anonymous'
      image.src = canvas.toDataURL('image/png')
      return image
    },
    // 实验截图复制
    dialogScreenshotCopy() {
      let self = this
      var clipboard = new self.Clipboard('.dialog-screenshot .button-style')
      clipboard.on('success', (e) => {
        self.$message({
          message: '复制成功，请在编辑器粘贴',
          type: 'success',
        })
        self.dialogScreenshot = false
        e.clearSelection()
      })
      clipboard.on('error', (e) => {
        // 不支持复制
        console.log('该浏览器不支持自动复制')
        // 释放内存
        clipboard.destroy()
      })
    },
    // 实验截图保存下载图片
    dialogScreenshotSave() {
      let self = this
      self.downloadFile('截图.png', self.dialogScreenshotUrl)
    },
    // 下载
    downloadFile(fileName, content) {
      let aLink = document.createElement('a')
      let blob = this.base64ToBlob(content) // new Blob([content]);

      let evt = document.createEvent('HTMLEvents')
      evt.initEvent('click', true, true) // initEvent 不加后两个参数在FF下会报错  事件类型，是否冒泡，是否阻止浏览器的默认行为
      aLink.download = fileName
      aLink.href = URL.createObjectURL(blob)

      // aLink.dispatchEvent(evt);
      aLink.dispatchEvent(
        new MouseEvent('click', {
          bubbles: true,
          cancelable: true,
          view: window,
        })
      )
    },
    // base64转blob
    base64ToBlob(code) {
      let parts = code.split(';base64,')
      let contentType = parts[0].split(':')[1]
      let raw = window.atob(parts[1])
      let rawLength = raw.length

      let uInt8Array = new Uint8Array(rawLength)

      for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i)
      }
      return new Blob([uInt8Array], { type: contentType })
    },
    // 虚机右侧菜单显示隐藏
    MirrorArrowFn() {
      let self = this
      if (self.mirrorRightWidth == -144) {
        self.mirrorRightWidth = 0
      } else {
        self.mirrorRightWidth = -144
      }
    },
  },
}
</script>

<style lang="scss">
@import './../../../styles/layout/color_variables';
/* 全屏下的样式 */
.fullSide {
  height: 100%;
  padding: 0 10px;
  background: #e5e4e5;
  position: absolute;
  top: 0;
  left: 0;
  border-right: 1px solid #cfcfce;
}
.fullSide ul {
  margin-top: 60px;
}
.fullSide li {
  text-align: center;
  margin: 37px 0;
  cursor: pointer;
}
.fullSide li i {
  color: #989898;
  font-size: 16px;
}
.fullSide li p {
  color: #989898;
  margin-top: 5px;
  font-size: 12px;
}
.fullSide li:hover p {
  color: #727272;
}
.fullSide li:hover i {
  color: #727272;
}

//步骤
.mask-bg {
  width: 250px;
  background: #fff;
  z-index: 999;
  position: absolute;
  height: 100%;
  left: -100%;
  top: 0px;
  transition: left 0.4s;
  -moz-transition: left 0.4s; /* Firefox 4 */
  -webkit-transition: left 0.4s; /* Safari 和 Chrome */
  ul {
    padding: 20px 10px;
    li {
      line-height: 50px;
      height: 50px;
      padding-left: 10px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
}
.mask {
  background: #7c7c7c;
  position: absolute;
  width: 100%;
  top: 0px;
  height: 100%;
  left: 0px;
  opacity: 0;
  display: none;
  z-index: 9;
}
.mask-bg .activeSteep {
  color: #1277eb;
}
.foot-content {
  display: flex;
  justify-content: space-between;
  padding: 10px 0;
  position: fixed;
  bottom: 0;
  left: 0%;
  overflow: hidden;
  border-top: 1px solid #e9ecef;
  z-index: 999;

  .nextvpage {
    margin-right: 20px;
    margin-left: 10px;
  }
  .icon-gengduo {
    font-size: 22px;
    padding-top: 5px;
    padding-left: 15px;
    cursor: pointer;
  }
}

#jx-modify-virtual-machine {
  position: relative;
  height: 100%;
  overflow: hidden;
  .el-dialog__wrapper {
    box-shadow: 1px 1px 20px rgba(0, 0, 0, 0.2);
  }
  .tab-main {
    .jx-main-content {
      width: 100%;
      background: $white;
      box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
      padding: 20px;
      box-sizing: border-box;
    }
  }
  .jx-content-tips {
    text-align: center;
    margin-top: 100px;
    padding-top: 0;
    box-shadow: none;
  }
  .el-dialog__footer {
    text-align: center;
    .dialog-footer {
      .el-button {
        width: 90px;
      }
    }
  }
  .jx-virtual-machine-header {
    height: 60px;
    line-height: 60px;
    background: #101937;
    color: $white;
    .jx-virtual-machine-header-name {
      display: inline-block;
      max-width: 200px;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
    .jx-virtual-machine-header-name:nth-child(1) {
      margin-left: 20px;
    }
    .jx-virtual-machine-nav {
      margin: 20px 0 0 30px;
      float: left;
      height: 40px;
      line-height: 40px;
      span {
        width: 90px;
        color: $white;
        cursor: pointer;
        text-align: center;
        border-radius: 5px 5px 0 0;
        transition: 0.3s;
        // &:hover{
        //     background: $white;
        //     color: #101937;
        // }
        &.active {
          background: $white;
          color: #101937;
        }
      }
    }
    .jx-virtual-machine-nav2 {
      width: 56%;
      float: right;
      @extend .jx-virtual-machine-nav;
    }
    .jx-virtual-machine-header-info {
      height: 60px;
      line-height: 60px;
      margin-right: 40px;
      color: #bbbbbb;
      cursor: pointer;
      i {
        position: relative;
        top: 1px;
        color: #bbbbbb;
      }
      &:hover {
        color: #ffffff;
        i {
          color: #ffffff;
        }
      }
    }
    .jx-virtual-machine-header-dropout {
      height: 60px;
      line-height: 60px;
      i {
        color: #fff;
        font-size: 20px;
        margin-right: 20px;
        cursor: pointer;
      }
    }
  }
  .jx-virtual-machine-main {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    .step-main-content {
      height: 100%;
      background: #fff;
      overflow-x: scroll;
      //导航
      .task-nav {
        margin: 10px 0 10px 0;
        padding-left: 20px;
      }
      .task-judge {
        width: 100%;
        display: flex;
        flex-flow: row wrap;
        justify-content: flex-end;
        box-sizing: border-box;
        padding: 20px;
        .adds {
          margin-right: 20px;
        }
        .judge {
          margin: 15px 0 30px 0;
          width: 100%;
          padding: 15px;
          box-sizing: border-box;
          background: #f8f8f8;
          .el-radio-group {
            width: 100%;
          }
          .judge-title {
            margin-right: 20px;
            width: 100%;
            font-size: 16px;
            font-weight: bold;
            color: #3c86ea;
          }
          .judge-info {
            width: 100%;
            border-radius: 2px;
            //   .el-input__inner {
            // 	width: 300px !important;
            //   }
            .amend {
              margin: 0px 19px 5px 542px;
            }
            .save-btn {
              display: flex;
              // display: -webkit-box;
              justify-content: flex-end;
            }
            .form-item {
              display: flex;
              flex-flow: wrap;
              margin: 20px 0 20px 0;
              .item-label {
                font-size: 14px;
                font-family: Microsoft YaHei;
                font-weight: bold;
                color: #232323;
                line-height: 36px;
                margin-right: 10px;
              }
              .addErrorCondition {
                display: inline-block;
                margin-left: 12px;
                width: 40px;
                border-radius: 5px;
                border: 1px solid #333;
                color: #333;
                font-size: 10px;
                line-height: 15px;
                text-align: center;
              }
            }
            .info-one {
              display: flex;
              width: 100%;
              flex-flow: nowrap;
              align-items: center;
            }
            .info-two {
              width: 100%;
              font-size: 14px;
              font-weight: bold;
              color: #232323;
              line-height: 36px;
              .el-radio-group {
                margin-bottom: 8px;
              }
              .el-textarea .el-input__count {
                font-weight: normal !important;
              }
              .more-info {
                width: 100%;
                .more-info-item {
                  display: flex;
                  height: 40px;
                  align-items: center;
                  margin-bottom: 5px;
                }
                span {
                  margin-right: 15px;
                  font-size: 13px;
                  font-weight: 400;
                  color: #6a6a6a;
                }
                .inputs {
                  margin-left: 7px;
                  width: 50px;
                  height: 20px;
                  background: #ffffff;
                  border: 1px solid #e0e0e0;
                  border-radius: 4px;
                }
                .el-input {
                  margin-left: 7px;
                  width: 50px;
                  height: 20px;
                  // background: #ffffff;
                  // border: 1px solid #e0e0e0;
                  // border-radius: 4px;
                  .el-input__inner {
                    width: 50px;
                    height: 20px;
                  }
                  /* chrome */
                  input::-webkit-outer-spin-button,
                  input::-webkit-inner-spin-button {
                    -webkit-appearance: none;
                  }
                  /* 火狐浏览器 */
                  input[type='number'] {
                    -moz-appearance: textfield;
                  }
                }
                .canceErrorCondition {
                  cursor: pointer;
                  font-size: 10px;
                  line-height: 8px;
                  width: 11px;
                  height: 10px;
                  border-radius: 3px;
                  border: 1px solid #333;
                  display: flex;
                  justify-content: center;
                  align-items: center;
                  .cance-line {
                    width: 6px;
                    height: 1px;
                    background-color: #333;
                  }
                }
              }
            }

            .info-three {
              width: 100%;
              margin: 10px 0 0 0;
              .el-radio-group {
                margin-bottom: 8px;
              }
            }
          }
        }
        .no-judge {
          width: 100%;
          height: 780px;
          display: flex;
          justify-content: center;
          align-items: center;
          .no-data-tips {
            text-align: center;
            p {
              margin-top: 10px;
            }
          }
        }
      }
      &::-webkit-scrollbar {
        width: 5px;
        height: 0;
      }

      &::-webkit-scrollbar-thumb {
        background: #c1c1c1;
      }
      .step-main-content-text {
        width: 100%;
        background: $white;
        margin-top: 10px;
        .display-hide-btn {
          float: right;
          margin: 10px 10px 20px 0;
        }
      }
      .step-main-btn-box {
        overflow: hidden;
        padding: 12px 16px 15px 15px;
        text-align: right;
        i {
          color: #385899;
          font-size: 16px;
          line-height: 16px;
          vertical-align: top;
          cursor: pointer;
        }
      }
      .step-main-btn-group {
        text-align: center;
        margin-top: 20px;
        button {
          width: 90px;
          &:first-child {
            // background: $btn-blue;
            // color: #fff;
            margin-right: 5px;
          }
        }
      }
    }
    .step-main-mirror {
      position: relative;
      width: 65%;
      height: 100%;
      // overflow-x: auto;
      // &::-webkit-scrollbar {
      //     width: 6px;
      // }
      // &::-webkit-scrollbar-thumb {
      //     background: #4d5368;
      //     border-radius: 6px;
      // }
      .mirror-iframe {
        border-left: 1px solid rgba(0, 0, 0, 0.07);
      }
      .mirror-iframe-tip {
        text-align: center;
        img {
          margin-top: 20%;
        }
        .mirror-iframe-tip-text {
          display: block;
          font-size: 16px;
          color: #727272;
          margin: 28px 0 18px;
        }
      }
      .step-main-mirror-dialog {
        position: absolute;
        right: 0;
        top: 0;
        bottom: 0;
        width: 144px;
        box-sizing: border-box;
        background: #2e2f33;
        transition: 0.3s;
        .step-main-mirror-dialog-block {
          height: 100%;
          overflow-x: scroll;
          padding: 0 24px;
          &::-webkit-scrollbar {
            width: 3px;
            height: 0;
          }

          &::-webkit-scrollbar-thumb {
            background: $white;
          }
        }
        .quit-machine {
          width: 100px;
          height: 26px;
          border-radius: 13px;
          background: #1277eb;
          display: flex;
          align-items: center;
          color: #ffffff;
          font-size: 14px;
          cursor: pointer;
          margin: 20px auto 0px;
          justify-content: center;
          &:hover {
            opacity: 0.9;
          }
          img {
            margin-right: 5px;
          }
        }
        .mirror-dialog-header {
          font-size: 14px;
          line-height: 18px;
          color: $white;
          padding: 20px 0;
          text-align: center;
          h2 {
            font-weight: normal;
            font-size: 16px;
            margin-bottom: 10px;
          }
          span {
            font-size: 18px;
            line-height: 18px;
            font-weight: 400;
            vertical-align: bottom;
          }
        }
        .mirror-dialog-item {
          border-top: solid 1px rgba(255, 255, 255, 0.3);
          padding: 15px 0;
          .item-btn {
            position: relative;
            line-height: 40px;
            font-size: 14px;
            color: $white;

            span {
              cursor: pointer;
              &:hover {
                color: #1277eb;
              }
            }
            i {
              // float: left;
              width: 22px;
              text-align: left;
              // margin-right: 5px;
              display: inline-block;
              vertical-align: -webkit-baseline-middle;
              &.icon-guanbifenxiang {
                font-size: 14px;
              }
              &:hover {
                color: #1277eb;
              }
            }
          }
        }
      }
      .step-main-mirror-arrow {
        position: absolute;
        top: 20%;
        right: 144px;
        width: 22px;
        height: 80px;
        line-height: 80px;
        text-align: center;
        background: #2e2f33;
        border-radius: 4px 0 0 4px;
        padding: 5px 0;
        cursor: pointer;
        transition: 0.2s;
        div {
          color: #fff;
          font-size: 14px;
          width: 22px;
          line-height: 26px;
          // &:after{
          //     content: '\003C';
          // }
          // &.active{
          //     &:after{
          //         content: '\003E';
          //     }
          // }
        }
      }
      .step-main-mirror-side {
        position: absolute;
        bottom: 50px;
        right: 150px;
        // width: 240px;
        height: 60px;
        background: #1c1f21;
        color: $white;
        text-align: center;
        border-radius: 5px;
        z-index: 2;
        li {
          float: left;
          width: 60px;
          height: 36px;
          display: block;
          font-size: 12px;
          margin-top: 14px;
          position: relative;
          cursor: pointer;
          border-right: solid 1px #353636;
          box-sizing: border-box;
          &:hover {
            color: #dfdfdf;
          }
          &:last-child {
            border-right: none;
          }
          .iconfont {
            display: block;
            margin-bottom: 2px;
            font-size: 20px;
          }
        }
      }
    }
  }
  //分享
  .dialog-share {
    .button-style {
      width: 90px;
    }

    .dialog-content {
      .share-item {
        width: 280px;
        height: 28px;
        line-height: 28px;
        margin: 0 auto;
        text-align: center;
        font-size: 14px;
        color: $title-gray;
        margin-top: 20px;
        span {
          float: left;
          width: 210px;
          border-right: solid 1px #e8e8e8;
          padding-right: 38px;
          text-align: right;
          box-sizing: border-box;
        }
        .el-switch {
          float: left;
          margin: 4px 0 0 30px;
        }
      }
    }
  }
  //分享桌面
  .dialog-share-desktop {
    .share-desktop-item {
      margin-bottom: 35px;
      &:last-child {
        margin-bottom: 0;
      }
      .item-label {
        float: left;
        width: 155px;
        height: 32px;
        line-height: 32px;
        text-align: right;
        font-size: 14px;
        color: $title-gray;
      }
      .el-radio-group {
        margin-top: 8px;
      }
    }
  }
  //实验截图
  .dialog-screenshot {
    .dialog-content {
      img {
        width: 763px;
        height: 440px;
      }
    }
  }
  //学生手册
  .dialog-handbook {
    p {
      font-size: 14px;
      color: $title-gray;
      text-align: center;
      line-height: 48px;
      span {
        font-size: 18px;
        font-weight: bold;
      }
    }
    .handbook-item {
      .item-label {
        float: left;
        width: 155px;
        height: 48px;
        line-height: 48px;
        text-align: right;
        font-size: 14px;
        color: $title-gray;
      }
      .el-radio-group {
        margin-top: 17px;
      }
    }
  }
  //手册拖拽
  .dialog-hand-book {
    position: absolute; /*定位*/
    top: 20%;
    left: 30%;
    width: 800px;
    overflow: hidden;
    .v-note-wrapper {
      height: 100%;
    }
    .el-dialog__header {
      cursor: move;
    }
    .el-dialog {
      width: 100%;
      height: 100%;
      margin-top: 0 !important;
      .el-dialog__body {
        width: 100%;
        box-sizing: border-box;
        position: absolute;
        top: 46px;
        bottom: 0px;
        overflow: hidden !important;
        .dialog-body {
          height: 85%;
        }
      }
    }
  }
  //sftp上传弹窗样式
  .sftp-dialog {
    .el-dialog__body {
      padding: 38px 50px 30px;
    }
    .sftp-content {
      .sftp-header {
        border-bottom: solid 2px #dfdfdf;
        padding-bottom: 25px;
        margin-bottom: 25px;
        p {
          span {
            color: #5281c6;
          }
        }
      }
      p {
        font-size: 16px;
        line-height: 30px;
      }
      .sftp-title {
        font-size: 16px;
        color: #333;
        font-weight: bold;
        margin-bottom: 15px;
      }
      .sftp-desc {
        p {
          span {
            padding: 5px 10px;
            border-radius: 5px;
            background: #eeeeee;
            font-size: 14px;
            margin: 0 5px;
          }
          i {
            margin-left: 5px;
            color: #5281c6;
            position: relative;
            &:last-child {
              margin-left: 40px;
            }
            img {
              position: absolute;
              right: -28px;
              top: -20px;
            }
          }
        }
        .desc-item {
          margin-top: 30px;
          height: 60px;
          .item-pic {
            float: left;
          }
          a {
            float: left;
            font-size: 14px;
            margin-top: 12px;
            i {
              font-size: 18px;
              vertical-align: sub;
              margin-left: 24px;
            }
          }
          // overflow-y: scroll;
          // &::-webkit-scrollbar {
          //     width: 3px;
          // }

          // &::-webkit-scrollbar-thumb {
          //     background: #5281c6;
          // }
        }
      }
    }
  }
  //实训项目制作剪切板
  .cut-dialog {
    .cut-title {
      margin-bottom: 15px;
      p {
        font-size: 14px;
        span {
          font-size: 16px;
        }
      }
    }
    .el-form {
      .el-form-item {
        .el-form-item__content {
          height: auto;
        }
        .desc-num {
          float: right;
          margin-top: 170px;
          color: #bbbbbb;
        }
        .el-textarea {
          float: left;
          width: 85%;
          textarea {
            height: 200px;
            resize: none;
          }
          .el-textarea__inner {
            min-height: 200px;
            overflow-y: scroll;

            &::-webkit-scrollbar {
              width: 5px;
            }

            &::-webkit-scrollbar-thumb {
              background: #6589ae;
              border-radius: 2px;
            }
          }
        }
      }
    }
  }
  // 上传流程
  .common-tool-dialog {
    .el-input {
      float: left;
    }
    .version-file {
      padding: 0 40px;
      .el-form-item {
        margin-bottom: 0;
      }
      .el-button {
        float: left;
        position: relative;
        background: #1277eb;
        color: #fff;
        border-radius: 5px;
        width: 100px;
        height: 36px;
        line-height: 36px;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        cursor: pointer;
        span {
          display: block;
          cursor: pointer;
        }
      }
      input {
        position: absolute;
        width: 100px;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
        background: #cc281a;
        opacity: 0;
        cursor: pointer;
      }
    }
  }
  // 学生手册显隐
  .dialog-display-hide {
    .el-table .blue-row {
      background: #f5f7fb;
    }
  }
  // 镜像保存弹窗
  .dialog-mirror-save {
    .el-form {
      .el-form-item {
        position: relative;
        .el-form-item__content {
          height: auto;
        }
        .el-input {
          .el-input__inner {
            width: 230px;
          }
        }
        .el-textarea {
          height: 180px;
          .el-textarea__inner {
            width: 600px;
            resize: none;
          }
        }
      }
    }
    .distribution-swpier {
      position: relative;
      width: 700px;
      height: 64px;
      margin-bottom: 35px;
      margin-left: 55px;
      margin-top: 15px;
      .swiper-btn {
        background-image: none;
        outline: 0;
        top: 46px;
        i {
          font-size: 20px;
          color: #b1b1b1;
          &:hover {
            color: #474747;
          }
        }
      }
      .swiper-button-prev {
        left: -35px;
      }
      .swiper-button-next {
        right: -35px;
      }
    }
    .distribution-box {
      position: relative;
      width: 100%;
      height: 64px;
      line-height: 64px;
      background: #fff;
      border: solid 1px #d9d9d9;
      border-radius: 5px;
      text-align: center;
      cursor: pointer;
      box-sizing: border-box;
      img {
        width: 100%;
      }
      &:hover {
        border-color: #1277eb;
      }
      i {
        position: absolute;
        bottom: 28px;
        right: 8px;
        font-size: 14px;
        color: #3fdb9b;
        width: 14px;
        height: 14px;
      }
    }
  }
  // 重选配置弹窗样式
  .dialog-distribution {
    .el-dialog__body {
      min-height: 350px;
    }
    .el-form {
      padding: 0 50px;
      .el-dialog__body {
        position: relative;
      }
      .el-form-item-label {
        width: 95px;
      }
      .el-select {
        .el-input__inner {
          width: 80px;
        }
      }
      .el-input__icon {
        line-height: 32px;
      }
      .miror-item {
        .el-form-item {
          width: 305px;
          .el-select {
            margin-right: 5px;
            .el-input__inner {
              width: 150px;
            }
          }
        }
      }
      .config-item {
        .item-config {
          width: 340px;
          .el-select {
            .el-input__inner {
              width: 110px;
            }
          }
        }
        .item-cpu {
          .el-form-item__error {
            left: 95px;
          }
        }
        .el-form-item {
          width: 305px;
          .el-select {
            margin-right: 5px;
          }
          &.item-distributed {
            width: 270px;
            .el-select {
              .el-input__inner {
                width: 180px;
              }
            }
            .el-form-item__error {
              left: 85px;
            }
          }
          &.item-Gpu {
            width: 100px;
            .el-form-item-label {
              width: 55px;
            }
          }
        }
      }
      .form-title {
        font-size: 16px;
        color: #385899;
        width: 85px;
        margin-bottom: 15px;
        text-align: center;
      }
      .el-select {
        .el-input__inner {
          width: 180px;
        }
      }
      .el-cascader {
        line-height: 32px;
      }
      .item-node {
        .el-form-item {
          display: inline-block;
          width: 330px;
        }
      }
    }
    .el-dialog__footer {
      text-align: center;
      .el-button {
        width: auto;
      }
    }
    .button-style {
      min-width: 90px;
    }
    .el-radio-group {
      .el-radio__inner {
        border-color: #dcdfe6;
      }
      .el-radio {
        width: 80px;
      }
    }
    .virtual-step {
      width: 188px;
      border-bottom: solid 3px #dfdfdf;
      margin-top: 15px;
      margin-left: 80px;
      ul {
        li {
          float: left;
          width: 19px;
          height: 19px;
          line-height: 19px;
          color: #fff;
          font-size: 12px;
          text-align: center;
          border-radius: 10px;
          margin: -9px 0 0 0;
          background: #d9d9d9;
          cursor: pointer;
          &.active-disabled {
            cursor: not-allowed;
          }
          &:first-child {
            margin-left: 10%;
          }
          &:nth-child(2) {
            margin-left: 29%;
          }
          &:last-child {
            margin-left: 31%;
          }
          &.active {
            background: #1277eb;
          }
        }
      }
    }
    .distribution-item {
      width: 208px;
      height: 280px;
      border: solid 1px #e8e8e8;
      border-radius: 4px;
      position: absolute;
      right: 55px;
      top: 95px;
      .jx-course-box {
        margin-top: 25px;
        text-align: center;
        img {
          width: 155px;
        }
        span {
          display: block;
          font-size: 14px;
          color: $title-gray;
          margin-top: 10px;
        }
      }
      .jx-course-icon {
        position: absolute;
        right: 18px;
        top: -5px;
      }
      .jx-course-text {
        margin: 10px 24px 0;
        height: 145px;
        overflow-y: scroll;
        font-size: 12px;
        line-height: 16px;
        color: $table-gray;
        word-wrap: break-word;
        &::-webkit-scrollbar {
          width: 2px;
        }

        &::-webkit-scrollbar-thumb {
          background: #6c6c6c;
        }
      }
    }
  }
}
</style>

<style lang="scss">
#jx-modify-virtual-machine {
  .task-nav {
    .el-button {
      background-color: transparent;
      &:focus {
        background-color: #1277eb;
        color: #fff;
      }
      &:hover {
        background-color: #1277eb;
        color: #fff;
      }
    }
  }
  .task-judge {
    .el-button {
      background-color: #1277eb;
      &:hover {
        background: #66b1ff;
        border-color: #66b1ff;
        color: #fff;
      }
    }
    .save-btn {
      .el-button {
        background-color: transparent;
        color: #1277eb;
        border: 1px solid #1277eb;
        width: 70px;
        &:hover {
          background: #1277eb;
          border-color: #1277eb;
          color: #fff;
        }
      }
    }
  }
}
</style>
